Commit 7896ddcc authored by kinaba@chromium.org's avatar kinaba@chromium.org

Add FileSystemID parameter to IsolatedContext::RegisterFileSystemForPath.

With this change, nested filesystems mounted onto isolated context
can remember its original filesystem id, that unblocks the issue 370782
of drag-and-drop support in chromeos::FileSystemBackend.

BUG=370782, 386062
TBR=kaznacheev, benwells, dmichael, sky

Review URL: https://codereview.chromium.org/341043008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278666 0039d316-1c4b-4281-b951-d872f2087c98
parent 2a40daee
......@@ -199,6 +199,7 @@ TEST(FileSystemUtilTest, ExtractDrivePathFromFileSystemUrl) {
std::string isolated_id =
fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeForPlatformApp,
std::string(),
GetDriveMountPointPath(&profile).AppendASCII("bar/buz"),
&isolated_name);
EXPECT_EQ(
......
......@@ -96,12 +96,13 @@ void FileSystemBackend::ResolveURL(const fileapi::FileSystemURL& url,
const OpenFileSystemCallback& callback) {
std::string id;
fileapi::FileSystemType type;
std::string cracked_id;
base::FilePath path;
fileapi::FileSystemMountOption option;
if (!mount_points_->CrackVirtualPath(
url.virtual_path(), &id, &type, &path, &option) &&
url.virtual_path(), &id, &type, &cracked_id, &path, &option) &&
!system_mount_points_->CrackVirtualPath(
url.virtual_path(), &id, &type, &path, &option)) {
url.virtual_path(), &id, &type, &cracked_id, &path, &option)) {
// Not under a mount point, so return an error, since the root is not
// accessible.
GURL root_url = GURL(fileapi::GetExternalFileSystemRootURIString(
......@@ -188,12 +189,13 @@ void FileSystemBackend::GrantFileAccessToExtension(
std::string id;
fileapi::FileSystemType type;
std::string cracked_id;
base::FilePath path;
fileapi::FileSystemMountOption option;
if (!mount_points_->CrackVirtualPath(virtual_path,
&id, &type, &path, &option) &&
!system_mount_points_->CrackVirtualPath(virtual_path,
&id, &type, &path, &option)) {
if (!mount_points_->CrackVirtualPath(virtual_path, &id, &type, &cracked_id,
&path, &option) &&
!system_mount_points_->CrackVirtualPath(virtual_path, &id, &type,
&cracked_id, &path, &option)) {
return;
}
......@@ -278,7 +280,8 @@ fileapi::FileSystemOperation* FileSystemBackend::CreateFileSystemOperation(
bool FileSystemBackend::SupportsStreaming(
const fileapi::FileSystemURL& url) const {
return url.type() == fileapi::kFileSystemTypeDrive ||
url.type() == fileapi::kFileSystemTypeProvided;
url.type() == fileapi::kFileSystemTypeProvided ||
url.type() == fileapi::kFileSystemTypeDeviceMediaAsFileStorage;
}
scoped_ptr<webkit_blob::FileStreamReader>
......
......@@ -145,7 +145,8 @@ std::string RegisterFileSystem(WebContents* web_contents,
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
CHECK(web_contents->GetURL().SchemeIs(content::kChromeDevToolsScheme));
std::string file_system_id = isolated_context()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeLocal, path, registered_name);
fileapi::kFileSystemTypeNativeLocal, std::string(), path,
registered_name);
content::ChildProcessSecurityPolicy* policy =
content::ChildProcessSecurityPolicy::GetInstance();
......
......@@ -299,7 +299,7 @@ GrantedFileEntry CreateFileEntry(
DCHECK(isolated_context);
result.filesystem_id = isolated_context->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeForPlatformApp, path,
fileapi::kFileSystemTypeNativeForPlatformApp, std::string(), path,
&result.registered_name);
content::ChildProcessSecurityPolicy* policy =
......@@ -368,8 +368,10 @@ bool ValidateFileEntryAndGetPath(
.Append(relative_path);
fileapi::FileSystemType type;
fileapi::FileSystemMountOption mount_option;
std::string cracked_id;
if (!context->CrackVirtualPath(
virtual_path, &filesystem_id, &type, file_path, &mount_option)) {
virtual_path, &filesystem_id, &type, &cracked_id, file_path,
&mount_option)) {
*error = kInvalidParameters;
return false;
}
......
......@@ -129,7 +129,8 @@ class MediaFileValidatorTest : public InProcessBrowserTest {
ASSERT_TRUE(base::CreateDirectory(dest_path));
std::string dest_fsid =
fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeMedia, dest_path, NULL);
fileapi::kFileSystemTypeNativeMedia, std::string(), dest_path,
NULL);
size_t extension_index = filename.find_last_of(".");
ASSERT_NE(std::string::npos, extension_index);
......
......@@ -138,7 +138,7 @@ class NativeMediaFileUtilTest : public testing::Test {
content::CreateAllowFileAccessOptions());
filesystem_id_ = isolated_context()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeMedia, root_path(), NULL);
fileapi::kFileSystemTypeNativeMedia, std::string(), root_path(), NULL);
isolated_context()->AddReference(filesystem_id_);
}
......
......@@ -117,6 +117,7 @@ std::string PepperIsolatedFileSystemMessageFilter::CreateCrxFileSystem(
std::string kFirstLevelDirectory("crxfs");
return fileapi::IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeLocal,
std::string(),
extension->path(),
&kFirstLevelDirectory);
}
......
......@@ -456,11 +456,13 @@ TEST(ExternalMountPointsTest, CrackVirtualPath) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
std::string cracked_name;
fileapi::FileSystemType cracked_type;
std::string cracked_id;
base::FilePath cracked_path;
fileapi::FileSystemMountOption cracked_option;
EXPECT_EQ(kTestCases[i].expect_valid,
mount_points->CrackVirtualPath(base::FilePath(kTestCases[i].path),
&cracked_name, &cracked_type, &cracked_path, &cracked_option))
&cracked_name, &cracked_type, &cracked_id, &cracked_path,
&cracked_option))
<< "Test case index: " << i;
if (!kTestCases[i].expect_valid)
......@@ -473,6 +475,9 @@ TEST(ExternalMountPointsTest, CrackVirtualPath) {
<< "Test case index: " << i;
EXPECT_EQ(kTestCases[i].expect_name, cracked_name)
<< "Test case index: " << i;
// As of now we don't mount other filesystems with non-empty filesystem_id
// onto external mount points.
EXPECT_TRUE(cracked_id.empty()) << "Test case index: " << i;
}
}
......@@ -493,13 +498,16 @@ TEST(ExternalMountPointsTest, MountOption) {
std::string name;
fileapi::FileSystemType type;
std::string cracked_id;
fileapi::FileSystemMountOption option;
base::FilePath path;
EXPECT_TRUE(mount_points->CrackVirtualPath(
base::FilePath(FPL("nosync/file")), &name, &type, &path, &option));
base::FilePath(FPL("nosync/file")), &name, &type, &cracked_id, &path,
&option));
EXPECT_EQ(fileapi::COPY_SYNC_OPTION_NO_SYNC, option.copy_sync_option());
EXPECT_TRUE(mount_points->CrackVirtualPath(
base::FilePath(FPL("sync/file")), &name, &type, &path, &option));
base::FilePath(FPL("sync/file")), &name, &type, &cracked_id, &path,
&option));
EXPECT_EQ(fileapi::COPY_SYNC_OPTION_SYNC, option.copy_sync_option());
}
......
......@@ -114,6 +114,7 @@ TEST_F(FileSystemContextTest, NullExternalMountPoints) {
std::string isolated_id =
IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeLocal,
std::string(),
base::FilePath(DRIVE FPL("/test/isolated/root")),
&isolated_name);
// Register system external mount point.
......@@ -203,6 +204,7 @@ TEST_F(FileSystemContextTest, CrackFileSystemURL) {
const std::string kIsolatedFileSystemID =
IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeLocal,
std::string(),
base::FilePath(DRIVE FPL("/test/isolated/root")),
&isolated_file_system_name);
// Register system external mount point.
......@@ -357,6 +359,7 @@ TEST_F(FileSystemContextTest, CanServeURLRequest) {
std::string isolated_fs_id =
IsolatedContext::GetInstance()->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeLocal,
std::string(),
base::FilePath(DRIVE FPL("/test/isolated/root")),
&isolated_fs_name);
cracked_url = context->CrackURL(
......
......@@ -102,15 +102,17 @@ TEST_F(IsolatedContextTest, RegisterAndRevokeTest) {
.AppendASCII(names_[i]);
std::string cracked_id;
base::FilePath cracked_path;
std::string cracked_inner_id;
fileapi::FileSystemType cracked_type;
FileSystemMountOption cracked_option;
ASSERT_TRUE(isolated_context()->CrackVirtualPath(
virtual_path, &cracked_id, &cracked_type, &cracked_path,
&cracked_option));
virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
&cracked_path, &cracked_option));
ASSERT_EQ(kTestPaths[i].NormalizePathSeparators().value(),
cracked_path.value());
ASSERT_EQ(id_, cracked_id);
ASSERT_EQ(kFileSystemTypeDragged, cracked_type);
EXPECT_TRUE(cracked_inner_id.empty());
}
// Make sure GetRegisteredPath returns false for id_ since it is
......@@ -122,7 +124,8 @@ TEST_F(IsolatedContextTest, RegisterAndRevokeTest) {
isolated_context()->RemoveReference(id_);
std::string id2 = isolated_context()->RegisterFileSystemForPath(
kFileSystemTypeNativeLocal, base::FilePath(DRIVE FPL("/foo")), NULL);
kFileSystemTypeNativeLocal, std::string(),
base::FilePath(DRIVE FPL("/foo")), NULL);
// Make sure the GetDraggedFileInfo returns false for both ones.
ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id2, &toplevels));
......@@ -134,11 +137,11 @@ TEST_F(IsolatedContextTest, RegisterAndRevokeTest) {
// Try registering three more file systems for the same path as id2.
std::string id3 = isolated_context()->RegisterFileSystemForPath(
kFileSystemTypeNativeLocal, path, NULL);
kFileSystemTypeNativeLocal, std::string(), path, NULL);
std::string id4 = isolated_context()->RegisterFileSystemForPath(
kFileSystemTypeNativeLocal, path, NULL);
kFileSystemTypeNativeLocal, std::string(), path, NULL);
std::string id5 = isolated_context()->RegisterFileSystemForPath(
kFileSystemTypeNativeLocal, path, NULL);
kFileSystemTypeNativeLocal, std::string(), path, NULL);
// Remove file system for id4.
isolated_context()->AddReference(id4);
......@@ -201,21 +204,23 @@ TEST_F(IsolatedContextTest, CrackWithRelativePaths) {
std::string cracked_id;
base::FilePath cracked_path;
fileapi::FileSystemType cracked_type;
std::string cracked_inner_id;
FileSystemMountOption cracked_option;
if (!relatives[j].valid) {
ASSERT_FALSE(isolated_context()->CrackVirtualPath(
virtual_path, &cracked_id, &cracked_type, &cracked_path,
&cracked_option));
virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
&cracked_path, &cracked_option));
continue;
}
ASSERT_TRUE(isolated_context()->CrackVirtualPath(
virtual_path, &cracked_id, &cracked_type, &cracked_path,
&cracked_option));
virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
&cracked_path, &cracked_option));
ASSERT_EQ(kTestPaths[i].Append(relatives[j].path)
.NormalizePathSeparators().value(),
cracked_path.value());
ASSERT_EQ(id_, cracked_id);
ASSERT_EQ(kFileSystemTypeDragged, cracked_type);
EXPECT_TRUE(cracked_inner_id.empty());
}
}
}
......@@ -276,7 +281,7 @@ TEST_F(IsolatedContextTest, TestWithVirtualRoot) {
// that has no corresponding platform directory.
base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_);
ASSERT_TRUE(isolated_context()->CrackVirtualPath(
virtual_path, &cracked_id, NULL, &cracked_path, &cracked_option));
virtual_path, &cracked_id, NULL, NULL, &cracked_path, &cracked_option));
ASSERT_EQ(FPL(""), cracked_path.value());
ASSERT_EQ(id_, cracked_id);
......@@ -285,7 +290,7 @@ TEST_F(IsolatedContextTest, TestWithVirtualRoot) {
virtual_path = isolated_context()->CreateVirtualRootPath(
id_).AppendASCII("foo");
ASSERT_FALSE(isolated_context()->CrackVirtualPath(
virtual_path, &cracked_id, NULL, &cracked_path, &cracked_option));
virtual_path, &cracked_id, NULL, NULL, &cracked_path, &cracked_option));
}
TEST_F(IsolatedContextTest, CanHandleURL) {
......@@ -342,11 +347,14 @@ TEST_F(IsolatedContextTest, VirtualFileSystemTests) {
std::string cracked_id;
base::FilePath cracked_path;
std::string cracked_inner_id;
FileSystemMountOption cracked_option;
ASSERT_TRUE(isolated_context()->CrackVirtualPath(
whole_virtual_path, &cracked_id, NULL, &cracked_path, &cracked_option));
whole_virtual_path, &cracked_id, NULL, &cracked_inner_id,
&cracked_path, &cracked_option));
ASSERT_EQ(database_fsid, cracked_id);
ASSERT_EQ(test_virtual_path, cracked_path);
EXPECT_TRUE(cracked_inner_id.empty());
}
} // namespace content
......@@ -47,6 +47,7 @@ class TransientFileUtilTest : public testing::Test {
std::string name = "tmp";
std::string fsid = isolated_context->RegisterFileSystemForPath(
fileapi::kFileSystemTypeForTransientFile,
std::string(),
*file_path,
&name);
ASSERT_TRUE(!fsid.empty());
......
......@@ -764,7 +764,8 @@ void RenderViewHostImpl::DragTargetDragEnter(
std::string register_name;
std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
file_system_url.type(), file_system_url.path(), &register_name);
file_system_url.type(), file_system_url.filesystem_id(),
file_system_url.path(), &register_name);
policy->GrantReadFileSystem(renderer_id, filesystem_id);
// Note: We are using the origin URL provided by the sender here. It may be
......
......@@ -528,7 +528,7 @@ RuntimeGetPackageDirectoryEntryFunction::Run() {
std::string relative_path = kPackageDirectoryPath;
base::FilePath path = extension_->path();
std::string filesystem_id = isolated_context->RegisterFileSystemForPath(
fileapi::kFileSystemTypeNativeLocal, path, &relative_path);
fileapi::kFileSystemTypeNativeLocal, std::string(), path, &relative_path);
int renderer_id = render_view_host_->GetProcess()->GetID();
content::ChildProcessSecurityPolicy* policy =
......
......@@ -149,6 +149,7 @@ bool ExternalMountPoints::CrackVirtualPath(
const base::FilePath& virtual_path,
std::string* mount_name,
FileSystemType* type,
std::string* cracked_id,
base::FilePath* path,
FileSystemMountOption* mount_option) const {
DCHECK(mount_name);
......@@ -294,18 +295,20 @@ FileSystemURL ExternalMountPoints::CrackFileSystemURL(
std::string mount_name;
FileSystemType cracked_type;
std::string cracked_id;
base::FilePath cracked_path;
FileSystemMountOption cracked_mount_option;
if (!CrackVirtualPath(virtual_path, &mount_name, &cracked_type,
&cracked_path, &cracked_mount_option)) {
&cracked_id, &cracked_path, &cracked_mount_option)) {
return FileSystemURL();
}
return FileSystemURL(
url.origin(), url.mount_type(), url.virtual_path(),
!url.filesystem_id().empty() ? url.filesystem_id() : mount_name,
cracked_type, cracked_path, mount_name, cracked_mount_option);
cracked_type, cracked_path,
cracked_id.empty() ? mount_name : cracked_id, cracked_mount_option);
}
bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name,
......
......@@ -73,6 +73,7 @@ class WEBKIT_STORAGE_BROWSER_EXPORT ExternalMountPoints
const base::FilePath& virtual_path,
std::string* mount_name,
FileSystemType* type,
std::string* cracked_id,
base::FilePath* path,
FileSystemMountOption* mount_option) const OVERRIDE;
virtual FileSystemURL CrackURL(const GURL& url) const OVERRIDE;
......
......@@ -106,7 +106,9 @@ class IsolatedContext::Instance {
// IsolatedContext::RegisterFileSystemForPath() or
// IsolatedContext::RegisterFileSystemForVirtualPath().
// Most of isolated file system contexts should be of this type.
Instance(FileSystemType type, const MountPointInfo& file_info,
Instance(FileSystemType type,
const std::string& filesystem_id,
const MountPointInfo& file_info,
PathType path_type);
// For a multi-paths isolated file system. As of writing only file system
......@@ -117,6 +119,7 @@ class IsolatedContext::Instance {
~Instance();
FileSystemType type() const { return type_; }
const std::string& filesystem_id() const { return filesystem_id_; }
const MountPointInfo& file_info() const { return file_info_; }
const std::set<MountPointInfo>& files() const { return files_; }
int ref_counts() const { return ref_counts_; }
......@@ -131,6 +134,7 @@ class IsolatedContext::Instance {
private:
const FileSystemType type_;
const std::string filesystem_id_;
// For single-path instance.
const MountPointInfo file_info_;
......@@ -147,9 +151,11 @@ class IsolatedContext::Instance {
};
IsolatedContext::Instance::Instance(FileSystemType type,
const std::string& filesystem_id,
const MountPointInfo& file_info,
Instance::PathType path_type)
: type_(type),
filesystem_id_(filesystem_id),
file_info_(file_info),
path_type_(path_type),
ref_counts_(0) {
......@@ -218,6 +224,7 @@ std::string IsolatedContext::RegisterDraggedFileSystem(
std::string IsolatedContext::RegisterFileSystemForPath(
FileSystemType type,
const std::string& filesystem_id,
const base::FilePath& path_in,
std::string* register_name) {
base::FilePath path(path_in.NormalizePathSeparators());
......@@ -233,11 +240,12 @@ std::string IsolatedContext::RegisterFileSystemForPath(
}
base::AutoLock locker(lock_);
std::string filesystem_id = GetNewFileSystemId();
instance_map_[filesystem_id] = new Instance(type, MountPointInfo(name, path),
Instance::PLATFORM_PATH);
path_to_id_map_[path].insert(filesystem_id);
return filesystem_id;
std::string new_id = GetNewFileSystemId();
instance_map_[new_id] = new Instance(type, filesystem_id,
MountPointInfo(name, path),
Instance::PLATFORM_PATH);
path_to_id_map_[path].insert(new_id);
return new_id;
}
std::string IsolatedContext::RegisterFileSystemForVirtualPath(
......@@ -251,6 +259,7 @@ std::string IsolatedContext::RegisterFileSystemForVirtualPath(
std::string filesystem_id = GetNewFileSystemId();
instance_map_[filesystem_id] = new Instance(
type,
std::string(), // filesystem_id
MountPointInfo(register_name, cracked_path_prefix),
Instance::VIRTUAL_PATH);
path_to_id_map_[path].insert(filesystem_id);
......@@ -281,6 +290,7 @@ bool IsolatedContext::CrackVirtualPath(
const base::FilePath& virtual_path,
std::string* id_or_name,
FileSystemType* type,
std::string* cracked_id,
base::FilePath* path,
FileSystemMountOption* mount_option) const {
DCHECK(id_or_name);
......@@ -314,6 +324,8 @@ bool IsolatedContext::CrackVirtualPath(
const Instance* instance = found_instance->second;
if (type)
*type = instance->type();
if (cracked_id)
*cracked_id = instance->filesystem_id();
if (component_iter == components.end()) {
// The virtual root case.
......@@ -420,18 +432,22 @@ FileSystemURL IsolatedContext::CrackFileSystemURL(
return FileSystemURL();
std::string mount_name;
std::string cracked_mount_name;
FileSystemType cracked_type;
base::FilePath cracked_path;
FileSystemMountOption cracked_mount_option;
if (!CrackVirtualPath(url.path(), &mount_name, &cracked_type,
&cracked_path, &cracked_mount_option)) {
&cracked_mount_name, &cracked_path,
&cracked_mount_option)) {
return FileSystemURL();
}
return FileSystemURL(
url.origin(), url.mount_type(), url.virtual_path(),
!url.filesystem_id().empty() ? url.filesystem_id() : mount_name,
cracked_type, cracked_path, mount_name, cracked_mount_option);
cracked_type, cracked_path,
cracked_mount_name.empty() ? mount_name : cracked_mount_name,
cracked_mount_option);
}
bool IsolatedContext::UnregisterFileSystem(const std::string& filesystem_id) {
......
......@@ -93,12 +93,13 @@ class WEBKIT_STORAGE_BROWSER_EXPORT IsolatedContext : public MountPoints {
std::string RegisterDraggedFileSystem(const FileInfoSet& files);
// Registers a new isolated filesystem for a given |path| of filesystem
// |type| filesystem and returns a new filesystem ID.
// |type| filesystem with |filesystem_id| and returns a new filesystem ID.
// |path| must be an absolute path which has no parent references ('..').
// If |register_name| is non-null and has non-empty string the path is
// registered as the given |register_name|, otherwise it is populated
// with the name internally assigned to the path.
std::string RegisterFileSystemForPath(FileSystemType type,
const std::string& filesystem_id,
const base::FilePath& path,
std::string* register_name);
......@@ -148,6 +149,7 @@ class WEBKIT_STORAGE_BROWSER_EXPORT IsolatedContext : public MountPoints {
const base::FilePath& virtual_path,
std::string* filesystem_id,
FileSystemType* type,
std::string* cracked_id,
base::FilePath* path,
FileSystemMountOption* mount_option) const OVERRIDE;
virtual FileSystemURL CrackURL(const GURL& url) const OVERRIDE;
......
......@@ -87,6 +87,7 @@ class WEBKIT_STORAGE_BROWSER_EXPORT MountPoints {
virtual bool CrackVirtualPath(const base::FilePath& virtual_path,
std::string* mount_name,
FileSystemType* type,
std::string* cracked_id,
base::FilePath* path,
FileSystemMountOption* mount_option) const = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment