summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkerz@chromium.org <kerz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-20 22:19:17 +0000
committerkerz@chromium.org <kerz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-20 22:19:17 +0000
commiteeed85c4662942e0c9e557d36fa0d26a938058e5 (patch)
tree3e6e267779cd0de15b1dfb8543e399023a4b1342
parentfe2534f1d0294dadd3bc915982ef378906a2be57 (diff)
downloadchromium_src-eeed85c4662942e0c9e557d36fa0d26a938058e5.zip
chromium_src-eeed85c4662942e0c9e557d36fa0d26a938058e5.tar.gz
chromium_src-eeed85c4662942e0c9e557d36fa0d26a938058e5.tar.bz2
Merge 82266 - Fixed file/directory url resolution for external mount point provider.Per Eric's request, refactored FileSystemDirURLRequestJob and FileSystemURLRequestJob classes to resolve local file system through a new operation.BUG=chromium-os:14225TEST=added new test cases to FileSystemPathManagerTest.*, added FileSystemOperationTest.TestGetLocalFilePathSuccessReview URL: http://codereview.chromium.org/6864040
TBR=zelidrag@chromium.org Review URL: http://codereview.chromium.org/6882102 git-svn-id: svn://svn.chromium.org/chrome/branches/742/src@82372 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/platform_file.h1
-rw-r--r--chrome/browser/extensions/extension_file_browser_private_api.cc23
-rw-r--r--chrome/browser/extensions/extension_local_filesystem_apitest.cc33
-rw-r--r--chrome/browser/net/file_system_url_request_job_factory.cc8
-rw-r--r--content/browser/file_system/browser_file_system_helper.cc3
-rw-r--r--content/browser/file_system/file_system_dispatcher_host.cc4
-rw-r--r--webkit/chromeos/fileapi/cros_mount_point_provider.cc67
-rw-r--r--webkit/chromeos/fileapi/cros_mount_point_provider.h15
-rw-r--r--webkit/fileapi/file_system_callback_dispatcher.cc4
-rw-r--r--webkit/fileapi/file_system_callback_dispatcher.h5
-rw-r--r--webkit/fileapi/file_system_context.cc12
-rw-r--r--webkit/fileapi/file_system_context.h3
-rw-r--r--webkit/fileapi/file_system_context_unittest.cc2
-rw-r--r--webkit/fileapi/file_system_dir_url_request_job.cc82
-rw-r--r--webkit/fileapi/file_system_dir_url_request_job.h24
-rw-r--r--webkit/fileapi/file_system_dir_url_request_job_unittest.cc39
-rw-r--r--webkit/fileapi/file_system_file_util.cc8
-rw-r--r--webkit/fileapi/file_system_file_util.h10
-rw-r--r--webkit/fileapi/file_system_file_util_proxy.cc44
-rw-r--r--webkit/fileapi/file_system_file_util_proxy.h10
-rw-r--r--webkit/fileapi/file_system_mount_point_provider.h8
-rw-r--r--webkit/fileapi/file_system_operation.cc37
-rw-r--r--webkit/fileapi/file_system_operation.h4
-rw-r--r--webkit/fileapi/file_system_operation_unittest.cc30
-rw-r--r--webkit/fileapi/file_system_operation_write_unittest.cc4
-rw-r--r--webkit/fileapi/file_system_path_manager.cc12
-rw-r--r--webkit/fileapi/file_system_path_manager.h12
-rw-r--r--webkit/fileapi/file_system_path_manager_unittest.cc74
-rw-r--r--webkit/fileapi/file_system_url_request_job.cc55
-rw-r--r--webkit/fileapi/file_system_url_request_job.h29
-rw-r--r--webkit/fileapi/file_system_url_request_job_base.cc109
-rw-r--r--webkit/fileapi/file_system_url_request_job_base.h48
-rw-r--r--webkit/fileapi/file_system_url_request_job_unittest.cc42
-rw-r--r--webkit/fileapi/local_file_system_file_util.cc17
-rw-r--r--webkit/fileapi/local_file_system_file_util.h7
-rw-r--r--webkit/fileapi/sandbox_mount_point_provider.cc5
-rw-r--r--webkit/fileapi/sandbox_mount_point_provider.h4
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi2
-rw-r--r--webkit/plugins/ppapi/file_callbacks.cc4
-rw-r--r--webkit/plugins/ppapi/file_callbacks.h1
-rw-r--r--webkit/tools/test_shell/simple_file_system.cc8
-rw-r--r--webkit/tools/test_shell/simple_file_writer.cc4
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.cc4
43 files changed, 686 insertions, 231 deletions
diff --git a/base/platform_file.h b/base/platform_file.h
index cf01188..461b060 100644
--- a/base/platform_file.h
+++ b/base/platform_file.h
@@ -65,6 +65,7 @@ enum PlatformFileError {
PLATFORM_FILE_ERROR_ABORT = -12,
PLATFORM_FILE_ERROR_NOT_A_FILE = -13,
PLATFORM_FILE_ERROR_NOT_EMPTY = -14,
+ PLATFORM_FILE_ERROR_INVALID_URL = -15,
};
// Used to hold information about a given file.
diff --git a/chrome/browser/extensions/extension_file_browser_private_api.cc b/chrome/browser/extensions/extension_file_browser_private_api.cc
index 4aa7791..746a38b 100644
--- a/chrome/browser/extensions/extension_file_browser_private_api.cc
+++ b/chrome/browser/extensions/extension_file_browser_private_api.cc
@@ -195,6 +195,10 @@ class LocalFileSystemCallbackDispatcher
NOTREACHED();
}
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+ }
+
virtual void DidReadMetadata(const base::PlatformFileInfo& info,
const FilePath& unused) OVERRIDE {
NOTREACHED();
@@ -358,7 +362,7 @@ bool GetFileTasksFileBrowserFunction::RunImpl() {
// manifest instead of the default extension icon.
GURL icon =
ExtensionIconSource::GetIconURL(extension,
- Extension::EXTENSION_ICON_SMALLISH,
+ Extension::EXTENSION_ICON_BITTY,
ExtensionIconSet::MATCH_BIGGER,
false); // grayscale
task->SetString("iconUrl", icon.spec());
@@ -396,6 +400,10 @@ class ExecuteTasksFileSystemCallbackDispatcher
NOTREACHED();
}
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+ }
+
virtual void DidReadMetadata(const base::PlatformFileInfo& info,
const FilePath& unused) OVERRIDE {
NOTREACHED();
@@ -477,11 +485,12 @@ class ExecuteTasksFileSystemCallbackDispatcher
return false;
}
- FilePath root_path = path_manager->GetFileSystemRootPathOnFileThread(
- file_origin_url,
- fileapi::kFileSystemTypeExternal,
- virtual_path,
- false); // create
+ FilePath root_path =
+ path_manager->ValidateFileSystemRootAndGetPathOnFileThread(
+ file_origin_url,
+ fileapi::kFileSystemTypeExternal,
+ virtual_path,
+ false); // create
FilePath final_file_path = root_path.Append(virtual_path);
// Check if this file system entry exists first.
@@ -751,7 +760,7 @@ void FileDialogFunction::GetLocalPathsOnFileThread(const UrlList& file_urls) {
NOTREACHED();
continue;
}
- FilePath root = path_manager->GetFileSystemRootPathOnFileThread(
+ FilePath root = path_manager->ValidateFileSystemRootAndGetPathOnFileThread(
origin_url,
fileapi::kFileSystemTypeExternal,
FilePath(virtual_path),
diff --git a/chrome/browser/extensions/extension_local_filesystem_apitest.cc b/chrome/browser/extensions/extension_local_filesystem_apitest.cc
index 856cbb4..6b7d9c3 100644
--- a/chrome/browser/extensions/extension_local_filesystem_apitest.cc
+++ b/chrome/browser/extensions/extension_local_filesystem_apitest.cc
@@ -3,14 +3,43 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_mount_point_provider.h"
+#include "webkit/fileapi/file_system_path_manager.h"
#if defined(OS_CHROMEOS)
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, LocalFileSystem) {
+class FileSystemExtensionApiTest : public ExtensionApiTest {
+ public:
+ FileSystemExtensionApiTest() : test_mount_point_("/tmp") {
+ }
+
+ virtual ~FileSystemExtensionApiTest() {}
+
+ // Sets up test environment
+ void AddTmpMountPoint() {
+ // Add tmp mount point.
+ fileapi::FileSystemPathManager* path_manager =
+ browser()->profile()->GetFileSystemContext()->path_manager();
+ fileapi::ExternalFileSystemMountPointProvider* provider =
+ path_manager->external_provider();
+ provider->AddMountPoint(test_mount_point_);
+ }
+
+ private:
+ FilePath test_mount_point_;
+};
+
+IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, LocalFileSystem) {
+ AddTmpMountPoint();
ASSERT_TRUE(RunComponentExtensionTest("local_filesystem")) << message_;
+
}
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FileBrowserTest) {
+IN_PROC_BROWSER_TEST_F(FileSystemExtensionApiTest, FileBrowserTest) {
+ AddTmpMountPoint();
ASSERT_TRUE(RunExtensionTest("filesystem_handler")) << message_;
ASSERT_TRUE(RunComponentExtensionTest("filebrowser_component")) << message_;
}
diff --git a/chrome/browser/net/file_system_url_request_job_factory.cc b/chrome/browser/net/file_system_url_request_job_factory.cc
index 862b30c..ae9f118 100644
--- a/chrome/browser/net/file_system_url_request_job_factory.cc
+++ b/chrome/browser/net/file_system_url_request_job_factory.cc
@@ -15,19 +15,19 @@ namespace {
net::URLRequestJob* FileSystemURLRequestJobFactory(net::URLRequest* request,
const std::string& scheme) {
- fileapi::FileSystemPathManager* path_manager =
+ fileapi::FileSystemContext* file_system_context =
static_cast<ChromeURLRequestContext*>(request->context())
- ->file_system_context()->path_manager();
+ ->file_system_context();
const std::string path = request->url().path();
// If the path ends with a /, we know it's a directory. If the path refers
// to a directory and gets dispatched to FileSystemURLRequestJob, that class
// redirects back here, by adding a / to the URL.
if (!path.empty() && path[path.size() - 1] == '/') {
- return new fileapi::FileSystemDirURLRequestJob(request, path_manager,
+ return new fileapi::FileSystemDirURLRequestJob(request, file_system_context,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
}
- return new fileapi::FileSystemURLRequestJob(request, path_manager,
+ return new fileapi::FileSystemURLRequestJob(request, file_system_context,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
}
diff --git a/content/browser/file_system/browser_file_system_helper.cc b/content/browser/file_system/browser_file_system_helper.cc
index 9b4af18..db4bf3f 100644
--- a/content/browser/file_system/browser_file_system_helper.cc
+++ b/content/browser/file_system/browser_file_system_helper.cc
@@ -21,5 +21,6 @@ scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext(
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kAllowFileAccessFromFiles),
CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUnlimitedQuotaForFiles));
+ switches::kUnlimitedQuotaForFiles),
+ NULL);
}
diff --git a/content/browser/file_system/file_system_dispatcher_host.cc b/content/browser/file_system/file_system_dispatcher_host.cc
index a3ec0b7..5fcbc2e 100644
--- a/content/browser/file_system/file_system_dispatcher_host.cc
+++ b/content/browser/file_system/file_system_dispatcher_host.cc
@@ -46,6 +46,10 @@ class BrowserFileSystemCallbackDispatcher
dispatcher_host_->Send(new FileSystemMsg_DidSucceed(request_id_));
}
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+ }
+
virtual void DidReadMetadata(
const base::PlatformFileInfo& info,
const FilePath& platform_path) {
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.cc b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
index 9efc5cc..b5d40ae 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.cc
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
@@ -10,6 +10,7 @@
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/stringprintf.h"
+#include "base/synchronization/lock.h"
#include "base/utf_string_conversions.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystem.h"
@@ -26,11 +27,12 @@ typedef struct {
const char* web_root_path;
} FixedExposedPaths;
+const char kChromeUIScheme[] = "chrome";
+
// Top level file system elements exposed in FileAPI in ChromeOS:
FixedExposedPaths fixed_exposed_paths[] = {
{"/home/chronos/user/", "Downloads"},
{"/", "media"},
- {"/", "tmp"},
};
CrosMountPointProvider::CrosMountPointProvider(
@@ -55,43 +57,49 @@ std::string GetOriginIdentifierFromURL(
return web_security_origin.databaseIdentifier().utf8();
}
-void CrosMountPointProvider::GetFileSystemRootPath(
+bool CrosMountPointProvider::GetRootForVirtualPath(
+ const FilePath& virtual_path, FilePath* root_path) {
+ std::vector<FilePath::StringType> components;
+ virtual_path.GetComponents(&components);
+ if (components.size() < 1) {
+ return false;
+ }
+
+ base::AutoLock locker(lock_);
+ // Check if this root mount point is exposed by this provider.
+ MountPointMap::iterator iter = mount_point_map_.find(components[0]);
+ if (iter == mount_point_map_.end()) {
+ return false;
+ }
+ *root_path = iter->second;
+ return true;
+}
+
+void CrosMountPointProvider::ValidateFileSystemRootAndGetURL(
const GURL& origin_url,
fileapi::FileSystemType type,
bool create,
fileapi::FileSystemPathManager::GetRootPathCallback* callback_ptr) {
DCHECK(type == fileapi::kFileSystemTypeExternal);
-
std::string name(GetOriginIdentifierFromURL(origin_url));
name += ':';
name += fileapi::kExternalName;
-
- FilePath root_path = FilePath(fileapi::kExternalDir);
- callback_ptr->Run(!root_path.empty(), root_path, name);
+ FilePath root_path;
+ root_path = FilePath(fileapi::kExternalDir);
+ callback_ptr->Run(true, root_path, name);
}
-// Like GetFileSystemRootPath, but synchronous, and can be called only while
-// running on the file thread.
-FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
+FilePath CrosMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url,
fileapi::FileSystemType type,
const FilePath& virtual_path,
bool create) {
DCHECK(type == fileapi::kFileSystemTypeExternal);
-
- std::vector<FilePath::StringType> components;
- virtual_path.GetComponents(&components);
- if (components.size() < 1) {
- return FilePath();
- }
-
- // Check if this root directory is exposed by this provider.
- MountPointMap::iterator iter = mount_point_map_.find(components[0]);
- if (iter == mount_point_map_.end()) {
+ FilePath root_path;
+ if (!GetRootForVirtualPath(virtual_path, &root_path))
return FilePath();
- }
- return iter->second;
+ return root_path;
}
// TODO(zelidrag): Share this code with SandboxMountPointProvider impl.
@@ -104,14 +112,31 @@ bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url,
const FilePath& virtual_path) {
if (type != fileapi::kFileSystemTypeExternal)
return false;
+
+ // Permit access to mount points from internal WebUI.
+ if (origin_url.SchemeIs(kChromeUIScheme))
+ return true;
+
std::string extension_id = origin_url.host();
// Check first to make sure this extension has fileBrowserHander permissions.
if (!special_storage_policy_->IsFileHandler(extension_id))
return false;
+
return file_access_permissions_->HasAccessPermission(extension_id,
virtual_path);
}
+void CrosMountPointProvider::AddMountPoint(FilePath mount_point) {
+ base::AutoLock locker(lock_);
+ mount_point_map_.insert(std::pair<std::string, FilePath>(
+ mount_point.BaseName().value(), mount_point.DirName()));
+}
+
+void CrosMountPointProvider::RemoveMountPoint(FilePath mount_point) {
+ base::AutoLock locker(lock_);
+ mount_point_map_.erase(mount_point.BaseName().value());
+}
+
void CrosMountPointProvider::GrantFullAccessToExtension(
const std::string& extension_id) {
DCHECK(special_storage_policy_->IsFileHandler(extension_id));
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.h b/webkit/chromeos/fileapi/cros_mount_point_provider.h
index 23af15f..7c48df4 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.h
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/file_path.h"
+#include "base/synchronization/lock.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
#include "webkit/quota/special_storage_policy.h"
@@ -29,12 +30,12 @@ class CrosMountPointProvider
virtual bool IsAccessAllowed(const GURL& origin_url,
fileapi::FileSystemType type,
const FilePath& virtual_path) OVERRIDE;
- virtual void GetFileSystemRootPath(
+ virtual void ValidateFileSystemRootAndGetURL(
const GURL& origin_url,
fileapi::FileSystemType type,
bool create,
fileapi::FileSystemPathManager::GetRootPathCallback* callback) OVERRIDE;
- virtual FilePath GetFileSystemRootPathOnFileThread(
+ virtual FilePath ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url,
fileapi::FileSystemType type,
const FilePath& virtual_path,
@@ -47,12 +48,20 @@ class CrosMountPointProvider
const std::string& extension_id) OVERRIDE;
virtual void GrantFileAccessToExtension(
const std::string& extension_id, const FilePath& virtual_path) OVERRIDE;
- void RevokeAccessForExtension(const std::string& extension_id) OVERRIDE;
+ virtual void RevokeAccessForExtension(
+ const std::string& extension_id) OVERRIDE;
+ virtual void AddMountPoint(FilePath mount_point) OVERRIDE;
+ virtual void RemoveMountPoint(FilePath mount_point) OVERRIDE;
private:
class GetFileSystemRootPathTask;
typedef std::map<std::string, FilePath> MountPointMap;
+ // Gives the real file system's |root_path| for given |virtual_path|. Returns
+ // false when |virtual_path| cannot be mapped to the real file system.
+ bool GetRootForVirtualPath(const FilePath& virtual_path, FilePath* root_path);
+
+ base::Lock lock_; // Synchronize all access to path_map_.
MountPointMap mount_point_map_;
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
scoped_ptr<FileAccessPermissions> file_access_permissions_;
diff --git a/webkit/fileapi/file_system_callback_dispatcher.cc b/webkit/fileapi/file_system_callback_dispatcher.cc
index 1298979..618030b 100644
--- a/webkit/fileapi/file_system_callback_dispatcher.cc
+++ b/webkit/fileapi/file_system_callback_dispatcher.cc
@@ -17,4 +17,8 @@ void FileSystemCallbackDispatcher::DidOpenFile(
NOTREACHED();
}
+void FileSystemCallbackDispatcher::DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+}
+
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_callback_dispatcher.h b/webkit/fileapi/file_system_callback_dispatcher.h
index e2d3caa..63824ed 100644
--- a/webkit/fileapi/file_system_callback_dispatcher.h
+++ b/webkit/fileapi/file_system_callback_dispatcher.h
@@ -58,6 +58,11 @@ class FileSystemCallbackDispatcher {
virtual void DidOpenFile(
base::PlatformFile file,
base::ProcessHandle peer_handle);
+
+ // Callback for the real local platform path lookup, where possible.
+ // This isn't in WebFileSystemCallbacks.
+ virtual void DidGetLocalPath(const FilePath& local_path);
+
};
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc
index 205963a..7e0d62e 100644
--- a/webkit/fileapi/file_system_context.cc
+++ b/webkit/fileapi/file_system_context.cc
@@ -20,17 +20,21 @@ FileSystemContext::FileSystemContext(
const FilePath& profile_path,
bool is_incognito,
bool allow_file_access,
- bool unlimited_quota)
+ bool unlimited_quota,
+ FileSystemPathManager* path_manager)
: file_message_loop_(file_message_loop),
io_message_loop_(io_message_loop),
special_storage_policy_(special_storage_policy),
allow_file_access_from_files_(allow_file_access),
unlimited_quota_(unlimited_quota),
- path_manager_(new FileSystemPathManager(
- file_message_loop, profile_path, special_storage_policy, is_incognito,
- allow_file_access)),
+ path_manager_(path_manager),
usage_tracker_(new FileSystemUsageTracker(
file_message_loop, profile_path, is_incognito)) {
+ if (!path_manager) {
+ path_manager_.reset(new FileSystemPathManager(
+ file_message_loop, profile_path, special_storage_policy,
+ is_incognito, allow_file_access));
+ }
}
FileSystemContext::~FileSystemContext() {
diff --git a/webkit/fileapi/file_system_context.h b/webkit/fileapi/file_system_context.h
index cb4d207..aa1804a 100644
--- a/webkit/fileapi/file_system_context.h
+++ b/webkit/fileapi/file_system_context.h
@@ -37,7 +37,8 @@ class FileSystemContext
const FilePath& profile_path,
bool is_incognito,
bool allow_file_access_from_files,
- bool unlimited_quota);
+ bool unlimited_quota,
+ FileSystemPathManager* path_manager);
~FileSystemContext();
// This method can be called on any thread.
diff --git a/webkit/fileapi/file_system_context_unittest.cc b/webkit/fileapi/file_system_context_unittest.cc
index f1fff68..30ec54e 100644
--- a/webkit/fileapi/file_system_context_unittest.cc
+++ b/webkit/fileapi/file_system_context_unittest.cc
@@ -47,7 +47,7 @@ scoped_refptr<FileSystemContext> NewFileSystemContext(
base::MessageLoopProxy::CreateForCurrentThread(),
special_storage_policy,
FilePath(), false /* is_incognito */,
- allow_file_access, unlimited_quota);
+ allow_file_access, unlimited_quota, NULL);
}
} // anonymous namespace
diff --git a/webkit/fileapi/file_system_dir_url_request_job.cc b/webkit/fileapi/file_system_dir_url_request_job.cc
index d61dac0..fb75edf 100644
--- a/webkit/fileapi/file_system_dir_url_request_job.cc
+++ b/webkit/fileapi/file_system_dir_url_request_job.cc
@@ -19,6 +19,8 @@
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/fileapi/file_system_operation.h"
#include "webkit/fileapi/file_system_path_manager.h"
#include "webkit/fileapi/file_system_util.h"
@@ -29,29 +31,17 @@ using net::URLRequestStatus;
namespace fileapi {
FileSystemDirURLRequestJob::FileSystemDirURLRequestJob(
- URLRequest* request, FileSystemPathManager* path_manager,
+ URLRequest* request, FileSystemContext* file_system_context,
scoped_refptr<base::MessageLoopProxy> file_thread_proxy)
- : URLRequestJob(request),
- path_manager_(path_manager),
+ : FileSystemURLRequestJobBase(request, file_system_context,
+ file_thread_proxy),
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
- file_thread_proxy_(file_thread_proxy) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) {
}
FileSystemDirURLRequestJob::~FileSystemDirURLRequestJob() {
}
-void FileSystemDirURLRequestJob::Start() {
- MessageLoop::current()->PostTask(FROM_HERE,
- method_factory_.NewRunnableMethod(
- &FileSystemDirURLRequestJob::StartAsync));
-}
-
-void FileSystemDirURLRequestJob::Kill() {
- URLRequestJob::Kill();
- callback_factory_.RevokeAll();
-}
-
bool FileSystemDirURLRequestJob::ReadRawData(net::IOBuffer* dest, int dest_size,
int *bytes_read) {
@@ -64,47 +54,33 @@ bool FileSystemDirURLRequestJob::ReadRawData(net::IOBuffer* dest, int dest_size,
return true;
}
-bool FileSystemDirURLRequestJob::GetMimeType(std::string* mime_type) const {
- *mime_type = "text/html";
- return true;
+void FileSystemDirURLRequestJob::Start() {
+ MessageLoop::current()->PostTask(FROM_HERE,
+ method_factory_.NewRunnableMethod(
+ &FileSystemURLRequestJobBase::StartAsync));
}
-bool FileSystemDirURLRequestJob::GetCharset(std::string* charset) {
- *charset = "utf-8";
- return true;
+void FileSystemDirURLRequestJob::Kill() {
+ URLRequestJob::Kill();
+ callback_factory_.RevokeAll();
}
-void FileSystemDirURLRequestJob::StartAsync() {
- GURL origin_url;
- FileSystemType type;
- if (!CrackFileSystemURL(request_->url(), &origin_url, &type,
- &relative_dir_path_)) {
- NotifyFailed(net::ERR_INVALID_URL);
- return;
- }
-
- path_manager_->GetFileSystemRootPath(
- origin_url, type, false, // create
+void FileSystemDirURLRequestJob::DidGetLocalPath(
+ const FilePath& local_path) {
+ absolute_file_path_ = local_path;
+ base::FileUtilProxy::ReadDirectory(file_thread_proxy_, absolute_file_path_,
callback_factory_.NewCallback(
- &FileSystemDirURLRequestJob::DidGetRootPath));
+ &FileSystemDirURLRequestJob::DidReadDirectory));
}
-void FileSystemDirURLRequestJob::DidGetRootPath(bool success,
- const FilePath& root_path,
- const std::string& name) {
- if (!success) {
- NotifyFailed(net::ERR_FILE_NOT_FOUND);
- return;
- }
-
- absolute_dir_path_ = root_path.Append(relative_dir_path_);
+bool FileSystemDirURLRequestJob::GetMimeType(std::string* mime_type) const {
+ *mime_type = "text/html";
+ return true;
+}
- // We assume it's a directory if we've gotten here: either the path
- // ends with '/', or FileSystemDirURLRequestJob already statted it and
- // found it to be a directory.
- base::FileUtilProxy::ReadDirectory(file_thread_proxy_, absolute_dir_path_,
- callback_factory_.NewCallback(
- &FileSystemDirURLRequestJob::DidReadDirectory));
+bool FileSystemDirURLRequestJob::GetCharset(std::string* charset) {
+ *charset = "utf-8";
+ return true;
}
void FileSystemDirURLRequestJob::DidReadDirectory(
@@ -116,10 +92,10 @@ void FileSystemDirURLRequestJob::DidReadDirectory(
}
#if defined(OS_WIN)
- const string16& title = relative_dir_path_.value();
+ const string16& title = relative_file_path_.value();
#elif defined(OS_POSIX)
const string16& title = WideToUTF16(
- base::SysNativeMBToWide(relative_dir_path_.value()));
+ base::SysNativeMBToWide(relative_file_path_.value()));
#endif
data_.append(net::GetDirectoryListingHeader(ASCIIToUTF16("/") + title));
@@ -140,8 +116,4 @@ void FileSystemDirURLRequestJob::DidReadDirectory(
NotifyHeadersComplete();
}
-void FileSystemDirURLRequestJob::NotifyFailed(int rv) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
-}
-
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_dir_url_request_job.h b/webkit/fileapi/file_system_dir_url_request_job.h
index 3c0bfbb..e9f566f 100644
--- a/webkit/fileapi/file_system_dir_url_request_job.h
+++ b/webkit/fileapi/file_system_dir_url_request_job.h
@@ -16,15 +16,17 @@
#include "base/platform_file.h"
#include "base/task.h"
#include "net/url_request/url_request_job.h"
+#include "webkit/fileapi/file_system_url_request_job_base.h"
namespace fileapi {
-class FileSystemPathManager;
+class FileSystemContext;
+class FileSystemOperation;
// A request job that handles reading filesystem: URLs for directories.
-class FileSystemDirURLRequestJob : public net::URLRequestJob {
+class FileSystemDirURLRequestJob : public FileSystemURLRequestJobBase {
public:
FileSystemDirURLRequestJob(
- net::URLRequest* request, FileSystemPathManager* path_manager,
+ net::URLRequest* request, FileSystemContext* file_system_context,
scoped_refptr<base::MessageLoopProxy> file_thread_proxy);
// URLRequestJob methods:
@@ -38,25 +40,19 @@ class FileSystemDirURLRequestJob : public net::URLRequestJob {
// TODO(adamk): Implement GetResponseInfo and GetResponseCode to simulate
// an HTTP response.
- private:
+ protected:
+ // FileSystemURLRequestJobBase methods.
+ virtual void DidGetLocalPath(const FilePath& local_path);
+
virtual ~FileSystemDirURLRequestJob();
- void StartAsync();
- void DidGetRootPath(bool success, const FilePath& root_path,
- const std::string& name);
void DidReadDirectory(base::PlatformFileError error_code,
const std::vector<base::FileUtilProxy::Entry>& entries);
-
- void NotifyFailed(int rv);
+ fileapi::FileSystemOperation* GetNewOperation();
std::string data_;
- FilePath relative_dir_path_;
- FilePath absolute_dir_path_;
- FileSystemPathManager* const path_manager_;
-
ScopedRunnableMethodFactory<FileSystemDirURLRequestJob> method_factory_;
base::ScopedCallbackFactory<FileSystemDirURLRequestJob> callback_factory_;
- scoped_refptr<base::MessageLoopProxy> file_thread_proxy_;
DISALLOW_COPY_AND_ASSIGN(FileSystemDirURLRequestJob);
};
diff --git a/webkit/fileapi/file_system_dir_url_request_job_unittest.cc b/webkit/fileapi/file_system_dir_url_request_job_unittest.cc
index 6bbd688..6b2882b 100644
--- a/webkit/fileapi/file_system_dir_url_request_job_unittest.cc
+++ b/webkit/fileapi/file_system_dir_url_request_job_unittest.cc
@@ -27,6 +27,7 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_path_manager.h"
namespace fileapi {
@@ -35,6 +36,21 @@ namespace {
// We always use the TEMPORARY FileSystem in this test.
static const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/";
+class TestSpecialStoragePolicy : public quota::SpecialStoragePolicy {
+ public:
+ virtual bool IsStorageProtected(const GURL& origin) {
+ return false;
+ }
+
+ virtual bool IsStorageUnlimited(const GURL& origin) {
+ return true;
+ }
+
+ virtual bool IsFileHandler(const std::string& extension_id) {
+ return true;
+ }
+};
+
class FileSystemDirURLRequestJobTest : public testing::Test {
protected:
FileSystemDirURLRequestJobTest()
@@ -47,11 +63,19 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
file_thread_proxy_ = base::MessageLoopProxy::CreateForCurrentThread();
- path_manager_.reset(new FileSystemPathManager(
- file_thread_proxy_, temp_dir_.path(),
- NULL, false, false));
-
- path_manager_->GetFileSystemRootPath(
+ special_storage_policy_ = new TestSpecialStoragePolicy();
+ file_system_context_ =
+ new FileSystemContext(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ special_storage_policy_,
+ FilePath(), false /* is_incognito */,
+ false, true,
+ new FileSystemPathManager(
+ file_thread_proxy_, temp_dir_.path(),
+ NULL, false, false));
+
+ file_system_context_->path_manager()->ValidateFileSystemRootAndGetURL(
GURL("http://remote/"), kFileSystemTypeTemporary, true, // create
callback_factory_.NewCallback(
&FileSystemDirURLRequestJobTest::OnGetRootPath));
@@ -80,7 +104,7 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
delegate_->set_quit_on_redirect(true);
request_.reset(new net::URLRequest(url, delegate_.get()));
job_ = new FileSystemDirURLRequestJob(request_.get(),
- path_manager_.get(),
+ file_system_context_.get(),
file_thread_proxy_);
request_->Start();
@@ -110,7 +134,8 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
FilePath root_path_;
scoped_ptr<net::URLRequest> request_;
scoped_ptr<TestDelegate> delegate_;
- scoped_ptr<FileSystemPathManager> path_manager_;
+ scoped_refptr<TestSpecialStoragePolicy> special_storage_policy_;
+ scoped_refptr<FileSystemContext> file_system_context_;
scoped_refptr<base::MessageLoopProxy> file_thread_proxy_;
MessageLoop message_loop_;
diff --git a/webkit/fileapi/file_system_file_util.cc b/webkit/fileapi/file_system_file_util.cc
index aadc1cb..f012a33 100644
--- a/webkit/fileapi/file_system_file_util.cc
+++ b/webkit/fileapi/file_system_file_util.cc
@@ -61,6 +61,14 @@ PlatformFileError FileSystemFileUtil::EnsureFileExists(
return error_code;
}
+PlatformFileError FileSystemFileUtil::GetLocalFilePath(
+ FileSystemOperationContext* context,
+ const FilePath& virtual_path,
+ FilePath* local_path) {
+ *local_path = virtual_path;
+ return base::PLATFORM_FILE_OK;
+}
+
PlatformFileError FileSystemFileUtil::GetFileInfo(
FileSystemOperationContext* unused,
const FilePath& file_path,
diff --git a/webkit/fileapi/file_system_file_util.h b/webkit/fileapi/file_system_file_util.h
index 1169d02..9e62af3 100644
--- a/webkit/fileapi/file_system_file_util.h
+++ b/webkit/fileapi/file_system_file_util.h
@@ -13,6 +13,7 @@
#include "base/memory/singleton.h"
#include "base/platform_file.h"
#include "base/tracked_objects.h"
+#include "webkit/fileapi/file_system_types.h"
namespace base {
struct PlatformFileInfo;
@@ -24,7 +25,6 @@ namespace fileapi {
using base::PlatformFile;
using base::PlatformFileError;
-
class FileSystemOperationContext;
// A large part of this implementation is taken from base::FileUtilProxy.
@@ -64,6 +64,14 @@ class FileSystemFileUtil {
FileSystemOperationContext* context,
const FilePath& file_path, bool* created);
+ // Maps |virtual_path| given |context| into |local_path| which represents
+ // physical file location on the host OS. This may not always make sense for
+ // all subclasses.
+ virtual PlatformFileError GetLocalFilePath(
+ FileSystemOperationContext* context,
+ const FilePath& virtual_path,
+ FilePath* local_path);
+
// Retrieves the information about a file. It is invalid to pass NULL for the
// callback.
virtual PlatformFileError GetFileInfo(
diff --git a/webkit/fileapi/file_system_file_util_proxy.cc b/webkit/fileapi/file_system_file_util_proxy.cc
index 06a61c4..e5f8628 100644
--- a/webkit/fileapi/file_system_file_util_proxy.cc
+++ b/webkit/fileapi/file_system_file_util_proxy.cc
@@ -192,6 +192,37 @@ class RelayEnsureFileExists : public MessageLoopRelay {
bool created_;
};
+
+class RelayGetLocalPath : public MessageLoopRelay {
+ public:
+ RelayGetLocalPath(
+ const fileapi::FileSystemOperationContext& context,
+ const FilePath& virtual_path,
+ fileapi::FileSystemFileUtilProxy::GetLocalPathCallback* callback)
+ : MessageLoopRelay(context),
+ callback_(callback),
+ virtual_path_(virtual_path) {
+ DCHECK(callback);
+ }
+
+ protected:
+ virtual void RunWork() {
+ set_error_code(
+ file_system_file_util()->GetLocalFilePath(
+ context(), virtual_path_, &local_path_));
+ }
+
+ virtual void RunCallback() {
+ callback_->Run(error_code(), local_path_);
+ delete callback_;
+ }
+
+ private:
+ fileapi::FileSystemFileUtilProxy::GetLocalPathCallback* callback_;
+ FilePath virtual_path_;
+ FilePath local_path_;
+};
+
class RelayGetFileInfo : public MessageLoopRelay {
public:
RelayGetFileInfo(
@@ -437,8 +468,17 @@ bool FileSystemFileUtilProxy::EnsureFileExists(
context, message_loop_proxy, file_path, callback));
}
-// Retrieves the information about a file. It is invalid to pass NULL for the
-// callback.
+// static
+bool FileSystemFileUtilProxy::GetLocalPath(
+ const FileSystemOperationContext& context,
+ scoped_refptr<MessageLoopProxy> message_loop_proxy,
+ const FilePath& virtual_path,
+ GetLocalPathCallback* callback) {
+ return Start(FROM_HERE, message_loop_proxy,
+ new RelayGetLocalPath(context, virtual_path, callback));
+}
+
+// static
bool FileSystemFileUtilProxy::GetFileInfo(
const FileSystemOperationContext& context,
scoped_refptr<MessageLoopProxy> message_loop_proxy,
diff --git a/webkit/fileapi/file_system_file_util_proxy.h b/webkit/fileapi/file_system_file_util_proxy.h
index de4b320..e376314 100644
--- a/webkit/fileapi/file_system_file_util_proxy.h
+++ b/webkit/fileapi/file_system_file_util_proxy.h
@@ -40,6 +40,9 @@ class FileSystemFileUtilProxy {
const PlatformFileInfo& /* file_info */,
const FilePath& /* platform_path, where possible */
>::Type GetFileInfoCallback;
+ typedef Callback2<PlatformFileError /* error code */,
+ const FilePath& /* local_path, where possible */
+ >::Type GetLocalPathCallback;
typedef base::FileUtilProxy::ReadDirectoryCallback ReadDirectoryCallback;
// Creates or opens a file with the given flags. It is invalid to pass NULL
@@ -74,6 +77,13 @@ class FileSystemFileUtilProxy {
const FilePath& file_path,
EnsureFileExistsCallback* callback);
+ // Maps virtual file patch to its local physical location.
+ static bool GetLocalPath(
+ const FileSystemOperationContext& context,
+ scoped_refptr<MessageLoopProxy> message_loop_proxy,
+ const FilePath& virtual_path,
+ GetLocalPathCallback* callback);
+
// Retrieves the information about a file. It is invalid to pass NULL for the
// callback.
static bool GetFileInfo(
diff --git a/webkit/fileapi/file_system_mount_point_provider.h b/webkit/fileapi/file_system_mount_point_provider.h
index e331991..50e0d39 100644
--- a/webkit/fileapi/file_system_mount_point_provider.h
+++ b/webkit/fileapi/file_system_mount_point_provider.h
@@ -29,7 +29,7 @@ class FileSystemMountPointProvider {
// Retrieves the root path for the given |origin_url| and |type|, and
// calls the given |callback| with the root path and name.
// If |create| is true this also creates the directory if it doesn't exist.
- virtual void GetFileSystemRootPath(
+ virtual void ValidateFileSystemRootAndGetURL(
const GURL& origin_url,
FileSystemType type,
bool create,
@@ -37,7 +37,7 @@ class FileSystemMountPointProvider {
// Like GetFileSystemRootPath, but synchronous, and can be called only while
// running on the file thread.
- virtual FilePath GetFileSystemRootPathOnFileThread(
+ virtual FilePath ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url,
FileSystemType type,
const FilePath& virtual_path,
@@ -67,6 +67,10 @@ class ExternalFileSystemMountPointProvider
// Revoke file access from extension identified with |extension_id|.
virtual void RevokeAccessForExtension(
const std::string& extension_id) = 0;
+ // Adds a new mount point.
+ virtual void AddMountPoint(FilePath mount_point) = 0;
+ // Remove a mount point.
+ virtual void RemoveMountPoint(FilePath mount_point) = 0;
};
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc
index 15f8955..046a16f 100644
--- a/webkit/fileapi/file_system_operation.cc
+++ b/webkit/fileapi/file_system_operation.cc
@@ -60,7 +60,7 @@ void FileSystemOperation::OpenFileSystem(
// create an unpredictable directory name. Without that, we could lazily
// create the root later on the first filesystem write operation, and just
// return GetFileSystemRootURI() here.
- file_system_context()->path_manager()->GetFileSystemRootPath(
+ file_system_context()->path_manager()->ValidateFileSystemRootAndGetURL(
origin_url, type, create,
callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath));
}
@@ -232,6 +232,27 @@ void FileSystemOperation::FileExists(const GURL& path) {
&FileSystemOperation::DidFileExists));
}
+void FileSystemOperation::GetLocalPath(const GURL& path) {
+#ifndef NDEBUG
+ DCHECK(kOperationNone == pending_operation_);
+ pending_operation_ = kOperationGetLocalPath;
+#endif
+
+ FilePath virtual_path;
+ GURL origin_url;
+ FileSystemType type;
+ if (!VerifyFileSystemPathForRead(path, &origin_url, &type, &virtual_path)) {
+ delete this;
+ return;
+ }
+ file_system_operation_context_.set_src_origin_url(origin_url);
+ file_system_operation_context_.set_src_type(type);
+ FileSystemFileUtilProxy::GetLocalPath(
+ file_system_operation_context_,
+ proxy_, virtual_path, callback_factory_.NewCallback(
+ &FileSystemOperation::DidGetLocalPath));
+}
+
void FileSystemOperation::GetMetadata(const GURL& path) {
#ifndef NDEBUG
DCHECK(kOperationNone == pending_operation_);
@@ -531,6 +552,16 @@ void FileSystemOperation::DidFileExists(
delete this;
}
+void FileSystemOperation::DidGetLocalPath(
+ base::PlatformFileError rv,
+ const FilePath& local_path) {
+ if (rv == base::PLATFORM_FILE_OK)
+ dispatcher_->DidGetLocalPath(local_path);
+ else
+ dispatcher_->DidFail(rv);
+ delete this;
+}
+
void FileSystemOperation::DidGetMetadata(
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
@@ -623,7 +654,7 @@ bool FileSystemOperation::VerifyFileSystemPathForRead(
// We may want do more checks, but for now it just checks if the given
// URL is valid.
if (!CrackFileSystemURL(path, origin_url, type, virtual_path)) {
- dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_INVALID_URL);
return false;
}
if (!file_system_context()->path_manager()->IsAccessAllowed(
@@ -660,7 +691,7 @@ bool FileSystemOperation::VerifyFileSystemPathForWrite(
}
if (!CrackFileSystemURL(path, origin_url, type, virtual_path)) {
- dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_INVALID_URL);
return false;
}
if (!file_system_context()->path_manager()->IsAccessAllowed(
diff --git a/webkit/fileapi/file_system_operation.h b/webkit/fileapi/file_system_operation.h
index c726403..654b596 100644
--- a/webkit/fileapi/file_system_operation.h
+++ b/webkit/fileapi/file_system_operation.h
@@ -84,6 +84,7 @@ class FileSystemOperation {
const GURL& path,
int file_flags,
base::ProcessHandle peer_handle);
+ void GetLocalPath(const GURL& path);
// Try to cancel the current operation [we support cancelling write or
// truncate only]. Report failure for the current operation, then tell the
@@ -138,6 +139,8 @@ class FileSystemOperation {
base::PlatformFileError rv,
base::PassPlatformFile file,
bool created);
+ void DidGetLocalPath(base::PlatformFileError rv,
+ const FilePath& local_path);
// Helper for Write().
void OnFileOpenedForWrite(
@@ -194,6 +197,7 @@ class FileSystemOperation {
kOperationTruncate,
kOperationTouchFile,
kOperationOpenFile,
+ kOperationGetLocalPath,
kOperationCancel,
};
diff --git a/webkit/fileapi/file_system_operation_unittest.cc b/webkit/fileapi/file_system_operation_unittest.cc
index 292104b..934504d 100644
--- a/webkit/fileapi/file_system_operation_unittest.cc
+++ b/webkit/fileapi/file_system_operation_unittest.cc
@@ -4,14 +4,19 @@
#include "webkit/fileapi/file_system_operation.h"
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_temp_dir.h"
#include "base/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_util.h"
+#include "webkit/fileapi/file_system_mount_point_provider.h"
#include "webkit/fileapi/file_system_operation.h"
+#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/file_system_util.h"
namespace fileapi {
@@ -39,6 +44,8 @@ class FileSystemOperationTest : public testing::Test {
FileSystemOperation* operation();
+ void set_local_path(const FilePath& path) { local_path_ = path; }
+ const FilePath& local_path() const { return local_path_; }
void set_status(int status) { status_ = status; }
int status() const { return status_; }
void set_info(const base::PlatformFileInfo& info) { info_ = info; }
@@ -70,6 +77,7 @@ class FileSystemOperationTest : public testing::Test {
int status_;
base::PlatformFileInfo info_;
FilePath path_;
+ FilePath local_path_;
std::vector<base::FileUtilProxy::Entry> entries_;
DISALLOW_COPY_AND_ASSIGN(FileSystemOperationTest);
@@ -87,6 +95,11 @@ class MockDispatcher : public FileSystemCallbackDispatcher {
test_->set_status(kFileOperationSucceeded);
}
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ test_->set_local_path(local_path);
+ test_->set_status(kFileOperationSucceeded);
+ }
+
virtual void DidReadMetadata(
const base::PlatformFileInfo& info,
const FilePath& platform_path) {
@@ -126,6 +139,7 @@ FileSystemOperation* FileSystemOperationTest::operation() {
GURL origin_url("fake://fake.foo/");
operation->file_system_operation_context()->set_src_origin_url(origin_url);
operation->file_system_operation_context()->set_dest_origin_url(origin_url);
+
return operation;
}
@@ -610,6 +624,22 @@ TEST_F(FileSystemOperationTest, TestExistsAndMetadataSuccess) {
EXPECT_EQ(file, path());
}
+TEST_F(FileSystemOperationTest, TestGetLocalFilePathSuccess) {
+ ScopedTempDir dir;
+ ASSERT_TRUE(dir.CreateUniqueTempDir());
+ operation()->GetLocalPath(URLForPath(dir.path()));
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, status());
+ EXPECT_EQ(local_path().value(), dir.path().value());
+
+ FilePath file;
+ file_util::CreateTemporaryFileInDir(dir.path(), &file);
+ operation()->GetLocalPath(URLForPath(file));
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kFileOperationSucceeded, status());
+ EXPECT_EQ(local_path().value(), file.value());
+}
+
TEST_F(FileSystemOperationTest, TestTypeMismatchErrors) {
ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
diff --git a/webkit/fileapi/file_system_operation_write_unittest.cc b/webkit/fileapi/file_system_operation_write_unittest.cc
index c387f4a..b6389a4 100644
--- a/webkit/fileapi/file_system_operation_write_unittest.cc
+++ b/webkit/fileapi/file_system_operation_write_unittest.cc
@@ -115,6 +115,10 @@ class MockDispatcher : public FileSystemCallbackDispatcher {
ADD_FAILURE();
}
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ ADD_FAILURE();
+ }
+
virtual void DidReadMetadata(
const base::PlatformFileInfo& info,
const FilePath& platform_path) {
diff --git a/webkit/fileapi/file_system_path_manager.cc b/webkit/fileapi/file_system_path_manager.cc
index cefdab8..898a5fa 100644
--- a/webkit/fileapi/file_system_path_manager.cc
+++ b/webkit/fileapi/file_system_path_manager.cc
@@ -54,19 +54,19 @@ FileSystemPathManager::FileSystemPathManager(
FileSystemPathManager::~FileSystemPathManager() {}
-void FileSystemPathManager::GetFileSystemRootPath(
+void FileSystemPathManager::ValidateFileSystemRootAndGetURL(
const GURL& origin_url, fileapi::FileSystemType type,
bool create, GetRootPathCallback* callback_ptr) {
switch (type) {
case kFileSystemTypeTemporary:
case kFileSystemTypePersistent:
- sandbox_provider_->GetFileSystemRootPath(
+ sandbox_provider_->ValidateFileSystemRootAndGetURL(
origin_url, type, create, callback_ptr);
break;
case kFileSystemTypeExternal:
if (external_provider_.get()) {
- external_provider_->GetFileSystemRootPath(
+ external_provider_->ValidateFileSystemRootAndGetURL(
origin_url, type, create, callback_ptr);
} else {
callback_ptr->Run(false, FilePath(), std::string());
@@ -79,18 +79,18 @@ void FileSystemPathManager::GetFileSystemRootPath(
}
}
-FilePath FileSystemPathManager::GetFileSystemRootPathOnFileThread(
+FilePath FileSystemPathManager::ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url, FileSystemType type, const FilePath& virtual_path,
bool create) {
switch (type) {
case kFileSystemTypeTemporary:
case kFileSystemTypePersistent:
- return sandbox_provider_->GetFileSystemRootPathOnFileThread(
+ return sandbox_provider_->ValidateFileSystemRootAndGetPathOnFileThread(
origin_url, type, virtual_path, create);
break;
case kFileSystemTypeExternal:
return external_provider_.get() ?
- external_provider_->GetFileSystemRootPathOnFileThread(
+ external_provider_->ValidateFileSystemRootAndGetPathOnFileThread(
origin_url, type, virtual_path, create) :
FilePath();
case kFileSystemTypeUnknown:
diff --git a/webkit/fileapi/file_system_path_manager.h b/webkit/fileapi/file_system_path_manager.h
index f914a7d..1dc86a9 100644
--- a/webkit/fileapi/file_system_path_manager.h
+++ b/webkit/fileapi/file_system_path_manager.h
@@ -55,15 +55,15 @@ class FileSystemPathManager {
// Retrieves the root path for the given |origin_url| and |type|, and
// calls the given |callback| with the root path and name.
// If |create| is true this also creates the directory if it doesn't exist.
- virtual void GetFileSystemRootPath(const GURL& origin_url,
- FileSystemType type,
- bool create,
- FileSystemPathManager::GetRootPathCallback*
- callback);
+ virtual void ValidateFileSystemRootAndGetURL(
+ const GURL& origin_url,
+ FileSystemType type,
+ bool create,
+ FileSystemPathManager::GetRootPathCallback* callback);
// Like GetFileSystemRootPath, but synchronous, and can be called only while
// running on the file thread.
- virtual FilePath GetFileSystemRootPathOnFileThread(
+ virtual FilePath ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url,
FileSystemType type,
const FilePath& virtual_path,
diff --git a/webkit/fileapi/file_system_path_manager_unittest.cc b/webkit/fileapi/file_system_path_manager_unittest.cc
index dbdef10..e36a97e 100644
--- a/webkit/fileapi/file_system_path_manager_unittest.cc
+++ b/webkit/fileapi/file_system_path_manager_unittest.cc
@@ -15,6 +15,8 @@
#include "base/memory/scoped_temp_dir.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
+#include "base/sys_string_conversions.h"
+#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_util.h"
@@ -59,19 +61,26 @@ const struct RootPathTest {
"https_bar.com_0" PS "Temporary" },
{ fileapi::kFileSystemTypePersistent, "https://bar.com/",
"https_bar.com_0" PS "Persistent" },
+#if defined(OS_CHROMEOS)
+ { fileapi::kFileSystemTypeExternal, "chrome-extension://foo/",
+ "chrome-extension__0" PS "External" },
+#endif
};
const struct RootPathFileURITest {
fileapi::FileSystemType type;
const char* origin_url;
const char* expected_path;
+ const char* virtual_path;
} kRootPathFileURITestCases[] = {
{ fileapi::kFileSystemTypeTemporary, "file:///",
- "file__0" PS "Temporary" },
+ "file__0" PS "Temporary", NULL },
{ fileapi::kFileSystemTypePersistent, "file:///",
- "file__0" PS "Persistent" },
- // TODO(zelidrag): Add fileapi::kFileSystemTypeLocal test cases here once
- // we fix ChromeOS build of this test.
+ "file__0" PS "Persistent", NULL },
+#if defined(OS_CHROMEOS)
+ { fileapi::kFileSystemTypeExternal, "chrome-extension://foo/",
+ "chrome-extension__0" PS "External", "testing" },
+#endif
};
const struct CheckValidPathTest {
@@ -163,6 +172,16 @@ const struct IsRestrictedNameTest {
{ FILE_PATH_LITERAL("|ab"), true, },
};
+FilePath UTF8ToFilePath(const std::string& str) {
+ FilePath::StringType result;
+#if defined(OS_POSIX)
+ result = base::SysWideToNativeMB(UTF8ToWide(str));
+#elif defined(OS_WIN)
+ result = UTF8ToUTF16(str);
+#endif
+ return FilePath(result);
+}
+
class TestSpecialStoragePolicy : public quota::SpecialStoragePolicy {
public:
virtual bool IsStorageProtected(const GURL& origin) {
@@ -197,18 +216,24 @@ class FileSystemPathManagerTest : public testing::Test {
FileSystemPathManager* NewPathManager(
bool incognito,
bool allow_file_access) {
- return new FileSystemPathManager(
+ FileSystemPathManager* manager = new FileSystemPathManager(
base::MessageLoopProxy::CreateForCurrentThread(),
data_dir_.path(),
scoped_refptr<quota::SpecialStoragePolicy>(
new TestSpecialStoragePolicy()),
incognito,
allow_file_access);
+#if defined(OS_CHROMEOS)
+ fileapi::ExternalFileSystemMountPointProvider* ext_provider =
+ manager->external_provider();
+ ext_provider->AddMountPoint(FilePath("/tmp/testing"));
+#endif
+ return manager;
}
void OnGetRootPath(bool success,
- const FilePath& root_path,
- const std::string& name) {
+ const FilePath& root_path,
+ const std::string& name) {
root_path_callback_status_ = success;
root_path_ = root_path;
file_system_name_ = name;
@@ -219,7 +244,7 @@ class FileSystemPathManagerTest : public testing::Test {
fileapi::FileSystemType type,
bool create,
FilePath* root_path) {
- manager->GetFileSystemRootPath(origin_url, type, create,
+ manager->ValidateFileSystemRootAndGetURL(origin_url, type, create,
callback_factory_.NewCallback(
&FileSystemPathManagerTest::OnGetRootPath));
MessageLoop::current()->RunAllPending();
@@ -233,6 +258,12 @@ class FileSystemPathManagerTest : public testing::Test {
return data_dir_.path().Append(
SandboxMountPointProvider::kFileSystemDirectory);
}
+ FilePath external_file_system_path() {
+ return UTF8ToFilePath(std::string(fileapi::kExternalDir));
+ }
+ FilePath external_file_path_root() {
+ return UTF8ToFilePath(std::string("/tmp"));
+ }
private:
ScopedTempDir data_dir_;
@@ -261,10 +292,17 @@ TEST_F(FileSystemPathManagerTest, GetRootPathCreateAndExamine) {
kRootPathTestCases[i].type,
true /* create */, &root_path));
- FilePath expected = file_system_path().AppendASCII(
- kRootPathTestCases[i].expected_path);
- EXPECT_EQ(expected.value(), root_path.DirName().value());
- EXPECT_TRUE(file_util::DirectoryExists(root_path));
+ if (kRootPathTestCases[i].type != fileapi::kFileSystemTypeExternal) {
+ FilePath expected = file_system_path().AppendASCII(
+ kRootPathTestCases[i].expected_path);
+ EXPECT_EQ(expected.value(), root_path.DirName().value());
+ EXPECT_TRUE(file_util::DirectoryExists(root_path));
+ } else {
+ // External file system root path is virtual one and does not match
+ // anything from the actual file system.
+ EXPECT_EQ(external_file_system_path().value(),
+ root_path.value());
+ }
ASSERT_TRUE(returned_root_path.size() > i);
returned_root_path[i] = root_path;
}
@@ -355,10 +393,14 @@ TEST_F(FileSystemPathManagerTest, GetRootPathFileURIWithAllowFlag) {
GURL(kRootPathFileURITestCases[i].origin_url),
kRootPathFileURITestCases[i].type,
true /* create */, &root_path));
- FilePath expected = file_system_path().AppendASCII(
- kRootPathFileURITestCases[i].expected_path);
- EXPECT_EQ(expected.value(), root_path.DirName().value());
- EXPECT_TRUE(file_util::DirectoryExists(root_path));
+ if (kRootPathFileURITestCases[i].type != fileapi::kFileSystemTypeExternal) {
+ FilePath expected = file_system_path().AppendASCII(
+ kRootPathFileURITestCases[i].expected_path);
+ EXPECT_EQ(expected.value(), root_path.DirName().value());
+ EXPECT_TRUE(file_util::DirectoryExists(root_path));
+ } else {
+ EXPECT_EQ(external_file_path_root().value(), root_path.value());
+ }
}
}
diff --git a/webkit/fileapi/file_system_url_request_job.cc b/webkit/fileapi/file_system_url_request_job.cc
index 81f6939..6b4732a 100644
--- a/webkit/fileapi/file_system_url_request_job.cc
+++ b/webkit/fileapi/file_system_url_request_job.cc
@@ -50,18 +50,17 @@ static net::HttpResponseHeaders* CreateHttpResponseHeaders() {
}
FileSystemURLRequestJob::FileSystemURLRequestJob(
- URLRequest* request, FileSystemPathManager* path_manager,
+ URLRequest* request, FileSystemContext* file_system_context,
scoped_refptr<base::MessageLoopProxy> file_thread_proxy)
- : URLRequestJob(request),
- path_manager_(path_manager),
+ : FileSystemURLRequestJobBase(request, file_system_context,
+ file_thread_proxy),
+ ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(
io_callback_(this, &FileSystemURLRequestJob::DidRead)),
stream_(NULL),
is_directory_(false),
- remaining_bytes_(0),
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)),
- file_thread_proxy_(file_thread_proxy) {
+ remaining_bytes_(0) {
}
FileSystemURLRequestJob::~FileSystemURLRequestJob() {
@@ -82,7 +81,6 @@ void FileSystemURLRequestJob::Kill() {
stream_->Close();
stream_.reset(NULL);
}
-
URLRequestJob::Kill();
callback_factory_.RevokeAll();
}
@@ -148,6 +146,12 @@ void FileSystemURLRequestJob::SetExtraRequestHeaders(
}
}
+void FileSystemURLRequestJob::DidGetLocalPath(const FilePath& local_path) {
+ absolute_file_path_ = local_path;
+ base::FileUtilProxy::GetFileInfo(file_thread_proxy_, absolute_file_path_,
+ callback_factory_.NewCallback(&FileSystemURLRequestJob::DidResolve));
+}
+
void FileSystemURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
if (response_info_.get())
*info = *response_info_;
@@ -159,34 +163,6 @@ int FileSystemURLRequestJob::GetResponseCode() const {
return URLRequestJob::GetResponseCode();
}
-void FileSystemURLRequestJob::StartAsync() {
- GURL origin_url;
- FileSystemType type;
- if (!CrackFileSystemURL(request_->url(), &origin_url, &type,
- &relative_file_path_)) {
- NotifyFailed(net::ERR_INVALID_URL);
- return;
- }
-
- path_manager_->GetFileSystemRootPath(
- origin_url, type, false, // create
- callback_factory_.NewCallback(&FileSystemURLRequestJob::DidGetRootPath));
-}
-
-void FileSystemURLRequestJob::DidGetRootPath(bool success,
- const FilePath& root_path,
- const std::string& name) {
- if (!success) {
- NotifyFailed(net::ERR_FILE_NOT_FOUND);
- return;
- }
-
- absolute_file_path_ = root_path.Append(relative_file_path_);
-
- base::FileUtilProxy::GetFileInfo(file_thread_proxy_, absolute_file_path_,
- callback_factory_.NewCallback(&FileSystemURLRequestJob::DidResolve));
-}
-
void FileSystemURLRequestJob::DidResolve(base::PlatformFileError error_code,
const base::PlatformFileInfo& file_info) {
// We may have been orphaned...
@@ -231,6 +207,9 @@ void FileSystemURLRequestJob::DidOpen(base::PlatformFileError error_code,
byte_range_.first_byte_position() + 1;
DCHECK_GE(remaining_bytes_, 0);
+ // TODO(adamk): Please remove this ScopedAllowIO once we support async seek on
+ // FileStream.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
// Do the seek at the beginning of the request.
if (remaining_bytes_ > 0 &&
byte_range_.first_byte_position() != 0 &&
@@ -278,8 +257,4 @@ bool FileSystemURLRequestJob::IsRedirectResponse(GURL* location,
return false;
}
-void FileSystemURLRequestJob::NotifyFailed(int rv) {
- NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
-}
-
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_url_request_job.h b/webkit/fileapi/file_system_url_request_job.h
index 6d0f6e3..dd3c45c 100644
--- a/webkit/fileapi/file_system_url_request_job.h
+++ b/webkit/fileapi/file_system_url_request_job.h
@@ -17,6 +17,7 @@
#include "net/base/completion_callback.h"
#include "net/http/http_byte_range.h"
#include "net/url_request/url_request_job.h"
+#include "webkit/fileapi/file_system_url_request_job_base.h"
class GURL;
@@ -25,13 +26,13 @@ class FileStream;
}
namespace fileapi {
-class FileSystemPathManager;
+class FileSystemContext;
// A request job that handles reading filesystem: URLs
-class FileSystemURLRequestJob : public net::URLRequestJob {
+class FileSystemURLRequestJob : public FileSystemURLRequestJobBase {
public:
FileSystemURLRequestJob(
- net::URLRequest* request, FileSystemPathManager* path_manager,
+ net::URLRequest* request, FileSystemContext* file_system_context,
scoped_refptr<base::MessageLoopProxy> file_thread_proxy);
// URLRequestJob methods:
@@ -46,35 +47,27 @@ class FileSystemURLRequestJob : public net::URLRequestJob {
// FilterContext methods (via URLRequestJob):
virtual bool GetMimeType(std::string* mime_type) const;
+ protected:
+ // FileSystemURLRequestJobBase methods.
+ virtual void DidGetLocalPath(const FilePath& local_path);
+
private:
virtual ~FileSystemURLRequestJob();
- void StartAsync();
- void DidGetRootPath(bool success, const FilePath& root_path,
- const std::string& name);
void DidResolve(base::PlatformFileError error_code,
const base::PlatformFileInfo& file_info);
void DidOpen(base::PlatformFileError error_code,
base::PassPlatformFile file, bool created);
void DidRead(int result);
- void NotifyFailed(int rv);
-
- FilePath relative_file_path_;
- FilePath absolute_file_path_;
- FileSystemPathManager* const path_manager_;
-
+ ScopedRunnableMethodFactory<FileSystemURLRequestJob> method_factory_;
+ base::ScopedCallbackFactory<FileSystemURLRequestJob> callback_factory_;
net::CompletionCallbackImpl<FileSystemURLRequestJob> io_callback_;
scoped_ptr<net::FileStream> stream_;
bool is_directory_;
scoped_ptr<net::HttpResponseInfo> response_info_;
-
- net::HttpByteRange byte_range_;
int64 remaining_bytes_;
-
- ScopedRunnableMethodFactory<FileSystemURLRequestJob> method_factory_;
- base::ScopedCallbackFactory<FileSystemURLRequestJob> callback_factory_;
- scoped_refptr<base::MessageLoopProxy> file_thread_proxy_;
+ net::HttpByteRange byte_range_;
DISALLOW_COPY_AND_ASSIGN(FileSystemURLRequestJob);
};
diff --git a/webkit/fileapi/file_system_url_request_job_base.cc b/webkit/fileapi/file_system_url_request_job_base.cc
new file mode 100644
index 0000000..d5c71b8
--- /dev/null
+++ b/webkit/fileapi/file_system_url_request_job_base.cc
@@ -0,0 +1,109 @@
+// Copyright (c) 2011 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/file_system_url_request_job_base.h"
+
+#include "base/message_loop.h"
+#include "net/base/net_errors.h"
+#include "net/url_request/url_request.h"
+
+using net::URLRequest;
+using net::URLRequestJob;
+using net::URLRequestStatus;
+
+namespace fileapi {
+
+class LocalPathCallbackDispatcher : public FileSystemCallbackDispatcher {
+ public:
+ explicit LocalPathCallbackDispatcher(
+ FileSystemURLRequestJobBase* request)
+ : request_(request),
+ io_loop_(base::MessageLoopProxy::CreateForCurrentThread()) {
+ DCHECK(request_);
+ }
+
+ // fileapi::FileSystemCallbackDispatcher overrides.
+ virtual void DidSucceed() OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ io_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(request_,
+ &FileSystemURLRequestJobBase::OnGetLocalPath,
+ local_path));
+ }
+
+ virtual void DidReadMetadata(const base::PlatformFileInfo& info,
+ const FilePath& unused) OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual void DidReadDirectory(
+ const std::vector<base::FileUtilProxy::Entry>& entries,
+ bool has_more) OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual void DidWrite(int64 bytes, bool complete) OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual void DidOpenFileSystem(const std::string& name,
+ const GURL& root_path) OVERRIDE {
+ NOTREACHED();
+ }
+
+ virtual void DidFail(base::PlatformFileError error_code) OVERRIDE {
+ io_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(request_,
+ &FileSystemURLRequestJobBase::RespondFailedOnIOThread,
+ error_code));
+ }
+
+ private:
+ FileSystemURLRequestJobBase* request_;
+ scoped_refptr<base::MessageLoopProxy> io_loop_;
+ DISALLOW_COPY_AND_ASSIGN(LocalPathCallbackDispatcher);
+};
+
+FileSystemURLRequestJobBase::FileSystemURLRequestJobBase(
+ URLRequest* request, FileSystemContext* file_system_context,
+ scoped_refptr<base::MessageLoopProxy> file_thread_proxy)
+ : URLRequestJob(request),
+ file_system_context_(file_system_context),
+ file_thread_proxy_(file_thread_proxy) {
+}
+
+FileSystemOperation* FileSystemURLRequestJobBase::GetNewOperation() {
+ LocalPathCallbackDispatcher* dispatcher =
+ new LocalPathCallbackDispatcher(this);
+ FileSystemOperation* operation = new FileSystemOperation(
+ dispatcher,
+ file_thread_proxy_,
+ file_system_context_,
+ NULL);
+ return operation;
+}
+
+void FileSystemURLRequestJobBase::StartAsync() {
+ GetNewOperation()->GetLocalPath(request_->url());
+}
+
+void FileSystemURLRequestJobBase::RespondFailedOnIOThread(int error_code) {
+ int rv = net::ERR_FILE_NOT_FOUND;
+ if (error_code == base::PLATFORM_FILE_ERROR_INVALID_URL)
+ rv = net::ERR_INVALID_URL;
+ NotifyFailed(rv);
+}
+
+void FileSystemURLRequestJobBase::NotifyFailed(int rv) {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
+}
+
+void FileSystemURLRequestJobBase::OnGetLocalPath(
+ const FilePath& local_path) {
+ DidGetLocalPath(local_path);
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/file_system_url_request_job_base.h b/webkit/fileapi/file_system_url_request_job_base.h
new file mode 100644
index 0000000..72cc1d2
--- /dev/null
+++ b/webkit/fileapi/file_system_url_request_job_base.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 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_FILE_SYSTEM_URL_REQUEST_JOB_BASE_H_
+#define WEBKIT_FILEAPI_FILE_SYSTEM_URL_REQUEST_JOB_BASE_H_
+#pragma once
+
+#include "base/file_path.h"
+#include "base/message_loop_proxy.h"
+#include "net/url_request/url_request_job.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_operation.h"
+
+namespace fileapi {
+
+// A base class for request jobs that handle reading filesystem: URLs for
+// files and directories.
+class FileSystemURLRequestJobBase : public net::URLRequestJob {
+ public:
+ FileSystemURLRequestJobBase(
+ net::URLRequest* request, FileSystemContext* file_system_context,
+ scoped_refptr<base::MessageLoopProxy> file_thread_proxy);
+
+ void StartAsync();
+
+ protected:
+ virtual void DidGetLocalPath(const FilePath& local_path) = 0 ;
+
+ void NotifyFailed(int rv);
+ void RespondFailedOnIOThread(int error_code);
+ FileSystemOperation* GetNewOperation();
+
+ FilePath relative_file_path_;
+ FilePath absolute_file_path_;
+ scoped_refptr<FileSystemContext> file_system_context_;
+ scoped_refptr<base::MessageLoopProxy> file_thread_proxy_;
+
+ private:
+ friend class LocalPathCallbackDispatcher;
+ void OnGetLocalPath(const FilePath& local_path);
+ DISALLOW_COPY_AND_ASSIGN(FileSystemURLRequestJobBase);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_FILE_SYSTEM_URL_REQUEST_JOB_BASE_H_
diff --git a/webkit/fileapi/file_system_url_request_job_unittest.cc b/webkit/fileapi/file_system_url_request_job_unittest.cc
index 18b74e0..62e6d8f 100644
--- a/webkit/fileapi/file_system_url_request_job_unittest.cc
+++ b/webkit/fileapi/file_system_url_request_job_unittest.cc
@@ -31,6 +31,7 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_path_manager.h"
namespace fileapi {
@@ -55,6 +56,21 @@ void FillBuffer(char* buffer, size_t len) {
}
}
+class TestSpecialStoragePolicy : public quota::SpecialStoragePolicy {
+ public:
+ virtual bool IsStorageProtected(const GURL& origin) {
+ return false;
+ }
+
+ virtual bool IsStorageUnlimited(const GURL& origin) {
+ return true;
+ }
+
+ virtual bool IsFileHandler(const std::string& extension_id) {
+ return true;
+ }
+};
+
class FileSystemURLRequestJobTest : public testing::Test {
protected:
FileSystemURLRequestJobTest()
@@ -65,13 +81,21 @@ class FileSystemURLRequestJobTest : public testing::Test {
virtual void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ special_storage_policy_ = new TestSpecialStoragePolicy();
// We use the main thread so that we can get the root path synchronously.
// TODO(adamk): Run this on the FILE thread we've created as well.
- path_manager_.reset(new FileSystemPathManager(
- base::MessageLoopProxy::CreateForCurrentThread(),
- temp_dir_.path(), NULL, false, false));
-
- path_manager_->GetFileSystemRootPath(
+ file_system_context_ =
+ new FileSystemContext(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ special_storage_policy_,
+ FilePath(), false /* is_incognito */,
+ false, true,
+ new FileSystemPathManager(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ temp_dir_.path(), NULL, false, false));
+
+ file_system_context_->path_manager()->ValidateFileSystemRootAndGetURL(
GURL("http://remote/"), kFileSystemTypeTemporary, true, // create
callback_factory_.NewCallback(
&FileSystemURLRequestJobTest::OnGetRootPath));
@@ -107,7 +131,9 @@ class FileSystemURLRequestJobTest : public testing::Test {
request_.reset(new net::URLRequest(url, delegate_.get()));
if (headers)
request_->SetExtraRequestHeaders(*headers);
- job_ = new FileSystemURLRequestJob(request_.get(), path_manager_.get(),
+ job_ = new FileSystemURLRequestJob(
+ request_.get(),
+ file_system_context_.get(),
base::MessageLoopProxy::CreateForCurrentThread());
request_->Start();
@@ -138,8 +164,8 @@ class FileSystemURLRequestJobTest : public testing::Test {
FilePath origin_root_path_;
scoped_ptr<net::URLRequest> request_;
scoped_ptr<TestDelegate> delegate_;
- scoped_ptr<FileSystemPathManager> path_manager_;
-
+ scoped_refptr<TestSpecialStoragePolicy> special_storage_policy_;
+ scoped_refptr<FileSystemContext> file_system_context_;
MessageLoop message_loop_;
base::ScopedCallbackFactory<FileSystemURLRequestJobTest> callback_factory_;
diff --git a/webkit/fileapi/local_file_system_file_util.cc b/webkit/fileapi/local_file_system_file_util.cc
index 068a052..7dad5b1 100644
--- a/webkit/fileapi/local_file_system_file_util.cc
+++ b/webkit/fileapi/local_file_system_file_util.cc
@@ -44,6 +44,20 @@ PlatformFileError LocalFileSystemFileUtil::EnsureFileExists(
context, local_path, created);
}
+PlatformFileError LocalFileSystemFileUtil::GetLocalFilePath(
+ FileSystemOperationContext* context,
+ const FilePath& virtual_path,
+ FilePath* local_path) {
+ FilePath path =
+ GetLocalPath(context, context->src_origin_url(), context->src_type(),
+ virtual_path);
+ if (path.empty())
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND;
+
+ *local_path = path;
+ return base::PLATFORM_FILE_OK;
+}
+
PlatformFileError LocalFileSystemFileUtil::GetFileInfo(
FileSystemOperationContext* context,
const FilePath& file_path,
@@ -170,7 +184,8 @@ FilePath LocalFileSystemFileUtil::GetLocalPath(
FileSystemType type,
const FilePath& virtual_path) {
FilePath root = context->file_system_context()->path_manager()->
- GetFileSystemRootPathOnFileThread(origin_url, type, virtual_path, false);
+ ValidateFileSystemRootAndGetPathOnFileThread(origin_url, type,
+ virtual_path, false);
if (root.empty())
return FilePath();
return root.Append(virtual_path);
diff --git a/webkit/fileapi/local_file_system_file_util.h b/webkit/fileapi/local_file_system_file_util.h
index 3e5855a..7e484aa 100644
--- a/webkit/fileapi/local_file_system_file_util.h
+++ b/webkit/fileapi/local_file_system_file_util.h
@@ -49,9 +49,14 @@ class LocalFileSystemFileUtil : public FileSystemFileUtil {
FileSystemOperationContext* context,
const FilePath& file_path, bool* created);
+ virtual PlatformFileError GetLocalFilePath(
+ FileSystemOperationContext* context,
+ const FilePath& virtual_file,
+ FilePath* local_path);
+
virtual PlatformFileError GetFileInfo(
FileSystemOperationContext* context,
- const FilePath& file_,
+ const FilePath& file,
base::PlatformFileInfo* file_info,
FilePath* platform_file);
diff --git a/webkit/fileapi/sandbox_mount_point_provider.cc b/webkit/fileapi/sandbox_mount_point_provider.cc
index 5e80296..51954ce 100644
--- a/webkit/fileapi/sandbox_mount_point_provider.cc
+++ b/webkit/fileapi/sandbox_mount_point_provider.cc
@@ -220,7 +220,7 @@ std::vector<FilePath> SandboxMountPointProvider::GetRootDirectories() const {
return std::vector<FilePath>();
}
-void SandboxMountPointProvider::GetFileSystemRootPath(
+void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
const GURL& origin_url, fileapi::FileSystemType type,
bool create, FileSystemPathManager::GetRootPathCallback* callback_ptr) {
scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback(callback_ptr);
@@ -239,7 +239,8 @@ void SandboxMountPointProvider::GetFileSystemRootPath(
task->Start(origin_url, origin_base_path, create);
};
-FilePath SandboxMountPointProvider::GetFileSystemRootPathOnFileThread(
+FilePath
+SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url, FileSystemType type, const FilePath& unused,
bool create) {
FilePath origin_base_path;
diff --git a/webkit/fileapi/sandbox_mount_point_provider.h b/webkit/fileapi/sandbox_mount_point_provider.h
index 51a9414..6f8cff8 100644
--- a/webkit/fileapi/sandbox_mount_point_provider.h
+++ b/webkit/fileapi/sandbox_mount_point_provider.h
@@ -37,7 +37,7 @@ class SandboxMountPointProvider : public FileSystemMountPointProvider {
// Retrieves the root path for the given |origin_url| and |type|, and
// calls the given |callback| with the root path and name.
// If |create| is true this also creates the directory if it doesn't exist.
- virtual void GetFileSystemRootPath(
+ virtual void ValidateFileSystemRootAndGetURL(
const GURL& origin_url,
FileSystemType type,
bool create,
@@ -45,7 +45,7 @@ class SandboxMountPointProvider : public FileSystemMountPointProvider {
// Like GetFileSystemRootPath, but synchronous, and can be called only while
// running on the file thread.
- virtual FilePath GetFileSystemRootPathOnFileThread(
+ virtual FilePath ValidateFileSystemRootAndGetPathOnFileThread(
const GURL& origin_url,
FileSystemType type,
const FilePath& unused,
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index ca25491..70de6fc 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -34,6 +34,8 @@
'file_system_types.h',
'file_system_url_request_job.cc',
'file_system_url_request_job.h',
+ 'file_system_url_request_job_base.cc',
+ 'file_system_url_request_job_base.h',
'file_system_usage_tracker.cc',
'file_system_usage_tracker.h',
'file_system_util.cc',
diff --git a/webkit/plugins/ppapi/file_callbacks.cc b/webkit/plugins/ppapi/file_callbacks.cc
index 6706d47..c4105ad 100644
--- a/webkit/plugins/ppapi/file_callbacks.cc
+++ b/webkit/plugins/ppapi/file_callbacks.cc
@@ -42,6 +42,10 @@ void FileCallbacks::DidSucceed() {
callback_->Run(PP_OK);
}
+void FileCallbacks::DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+}
+
void FileCallbacks::DidReadMetadata(
const base::PlatformFileInfo& file_info,
const FilePath& unused) {
diff --git a/webkit/plugins/ppapi/file_callbacks.h b/webkit/plugins/ppapi/file_callbacks.h
index 4bdaa1d..ff785b54 100644
--- a/webkit/plugins/ppapi/file_callbacks.h
+++ b/webkit/plugins/ppapi/file_callbacks.h
@@ -39,6 +39,7 @@ class FileCallbacks : public fileapi::FileSystemCallbackDispatcher {
// FileSystemCallbackDispatcher implementation.
virtual void DidSucceed();
+ virtual void DidGetLocalPath(const FilePath& local_path);
virtual void DidReadMetadata(
const base::PlatformFileInfo& file_info,
const FilePath& unused);
diff --git a/webkit/tools/test_shell/simple_file_system.cc b/webkit/tools/test_shell/simple_file_system.cc
index 6baa1a9..e5959ce 100644
--- a/webkit/tools/test_shell/simple_file_system.cc
+++ b/webkit/tools/test_shell/simple_file_system.cc
@@ -64,6 +64,11 @@ class SimpleFileSystemCallbackDispatcher
callbacks_->didSucceed();
}
+ // Callback to report information for a file.
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+ }
+
virtual void DidReadMetadata(const base::PlatformFileInfo& info,
const FilePath& platform_path) {
DCHECK(file_system_);
@@ -130,7 +135,8 @@ SimpleFileSystem::SimpleFileSystem() {
file_system_dir_.path(),
false /* incognito */,
true /* allow_file_access */,
- true /* unlimited_quota */);
+ true /* unlimited_quota */,
+ NULL);
} else {
LOG(WARNING) << "Failed to create a temp dir for the filesystem."
"FileSystem feature will be disabled.";
diff --git a/webkit/tools/test_shell/simple_file_writer.cc b/webkit/tools/test_shell/simple_file_writer.cc
index 657d247..bd9b282 100644
--- a/webkit/tools/test_shell/simple_file_writer.cc
+++ b/webkit/tools/test_shell/simple_file_writer.cc
@@ -96,6 +96,10 @@ class SimpleFileWriter::IOThreadProxy
proxy_->DidSucceed();
}
+ virtual void DidGetLocalPath(const FilePath& local_path) {
+ NOTREACHED();
+ }
+
virtual void DidFail(base::PlatformFileError error_code) {
proxy_->DidFail(error_code);
}
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
index ea2a78b..c8755d5 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
@@ -127,12 +127,12 @@ net::URLRequestJob* FileSystemURLRequestJobFactory(net::URLRequest* request,
if (!path.empty() && path[path.size() - 1] == '/') {
return new fileapi::FileSystemDirURLRequestJob(
request,
- fs_context->path_manager(),
+ fs_context,
SimpleResourceLoaderBridge::GetIoThread());
}
return new fileapi::FileSystemURLRequestJob(
request,
- fs_context->path_manager(),
+ fs_context,
SimpleResourceLoaderBridge::GetIoThread());
}