Commit c1000477 authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

[FS] Add support for external paths to drag&drop code.

A previous CL made opening files on special volumes via the file picker
and file handling APIs work, this also fixes the entry point for
drag&drop in a similar manner.

The bulk of this change is changing NativeFileSystemMangerImpl to use
the file system backends instead of base::File to determine if a path
is a file or a directory.

Bug: 1132102
Change-Id: I6c64356ea285b717ce63afc9c34d097bcde08016
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2432808Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812944}
parent acc6cc94
...@@ -15,10 +15,12 @@ namespace content { ...@@ -15,10 +15,12 @@ namespace content {
NativeFileSystemDragDropTokenImpl::NativeFileSystemDragDropTokenImpl( NativeFileSystemDragDropTokenImpl::NativeFileSystemDragDropTokenImpl(
NativeFileSystemManagerImpl* manager, NativeFileSystemManagerImpl* manager,
NativeFileSystemManagerImpl::PathType path_type,
const base::FilePath& file_path, const base::FilePath& file_path,
int renderer_process_id, int renderer_process_id,
mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken> receiver) mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken> receiver)
: manager_(manager), : manager_(manager),
path_type_(path_type),
file_path_(file_path), file_path_(file_path),
renderer_process_id_(renderer_process_id), renderer_process_id_(renderer_process_id),
token_(base::UnguessableToken::Create()) { token_(base::UnguessableToken::Create()) {
......
...@@ -26,6 +26,7 @@ class CONTENT_EXPORT NativeFileSystemDragDropTokenImpl ...@@ -26,6 +26,7 @@ class CONTENT_EXPORT NativeFileSystemDragDropTokenImpl
public: public:
NativeFileSystemDragDropTokenImpl( NativeFileSystemDragDropTokenImpl(
NativeFileSystemManagerImpl* manager, NativeFileSystemManagerImpl* manager,
NativeFileSystemManagerImpl::PathType path_type,
const base::FilePath& file_path, const base::FilePath& file_path,
int renderer_process_id, int renderer_process_id,
mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken> mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken>
...@@ -41,6 +42,8 @@ class CONTENT_EXPORT NativeFileSystemDragDropTokenImpl ...@@ -41,6 +42,8 @@ class CONTENT_EXPORT NativeFileSystemDragDropTokenImpl
int renderer_process_id() const { return renderer_process_id_; } int renderer_process_id() const { return renderer_process_id_; }
NativeFileSystemManagerImpl::PathType path_type() const { return path_type_; }
const base::FilePath& file_path() const { return file_path_; } const base::FilePath& file_path() const { return file_path_; }
const base::UnguessableToken& token() const { return token_; } const base::UnguessableToken& token() const { return token_; }
...@@ -56,6 +59,7 @@ class CONTENT_EXPORT NativeFileSystemDragDropTokenImpl ...@@ -56,6 +59,7 @@ class CONTENT_EXPORT NativeFileSystemDragDropTokenImpl
// Raw pointer since NativeFileSystemManagerImpl owns `this`. // Raw pointer since NativeFileSystemManagerImpl owns `this`.
NativeFileSystemManagerImpl* const manager_; NativeFileSystemManagerImpl* const manager_;
const NativeFileSystemManagerImpl::PathType path_type_;
const base::FilePath file_path_; const base::FilePath file_path_;
const int renderer_process_id_; const int renderer_process_id_;
const base::UnguessableToken token_; const base::UnguessableToken token_;
......
...@@ -151,10 +151,30 @@ bool IsValidTransferToken(NativeFileSystemTransferTokenImpl* token, ...@@ -151,10 +151,30 @@ bool IsValidTransferToken(NativeFileSystemTransferTokenImpl* token,
return true; return true;
} }
HandleType GetFileType(const base::FilePath& file_path) { void GetHandleTypeFromUrl(
base::File::Info file_info; storage::FileSystemURL url,
base::GetFileInfo(file_path, &file_info); base::OnceCallback<void(HandleType)> callback,
return file_info.is_directory ? HandleType::kDirectory : HandleType::kFile; scoped_refptr<base::SequencedTaskRunner> reply_runner,
storage::FileSystemOperationRunner* operation_runner) {
operation_runner->GetMetadata(
url, storage::FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY,
base::BindOnce(
[](scoped_refptr<base::SequencedTaskRunner> reply_runner,
base::OnceCallback<void(HandleType)> callback,
base::File::Error result, const base::File::Info& file_info) {
// If we couldn't determine if the url is a directory, it is treated
// as a file. If the web-exposed API is ever changed to allow
// reporting errors when getting a dropped file as a
// FileSystemHandle, this would be one place such errors could be
// triggered.
HandleType type = HandleType::kFile;
if (result == base::File::FILE_OK && file_info.is_directory) {
type = HandleType::kDirectory;
}
reply_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), type));
},
std::move(reply_runner), std::move(callback)));
} }
} // namespace } // namespace
...@@ -300,13 +320,14 @@ void NativeFileSystemManagerImpl::ChooseEntries( ...@@ -300,13 +320,14 @@ void NativeFileSystemManagerImpl::ChooseEntries(
} }
void NativeFileSystemManagerImpl::CreateNativeFileSystemDragDropToken( void NativeFileSystemManagerImpl::CreateNativeFileSystemDragDropToken(
PathType path_type,
const base::FilePath& file_path, const base::FilePath& file_path,
int renderer_id, int renderer_id,
mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken> mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken>
receiver) { receiver) {
auto drag_drop_token_impl = auto drag_drop_token_impl =
std::make_unique<NativeFileSystemDragDropTokenImpl>( std::make_unique<NativeFileSystemDragDropTokenImpl>(
this, file_path, renderer_id, std::move(receiver)); this, path_type, file_path, renderer_id, std::move(receiver));
auto token = drag_drop_token_impl->token(); auto token = drag_drop_token_impl->token();
drag_drop_tokens_.emplace(token, std::move(drag_drop_token_impl)); drag_drop_tokens_.emplace(token, std::move(drag_drop_token_impl));
} }
...@@ -360,30 +381,44 @@ void NativeFileSystemManagerImpl::ResolveDragDropToken( ...@@ -360,30 +381,44 @@ void NativeFileSystemManagerImpl::ResolveDragDropToken(
// Look up whether the file path that's associated with the token is a file or // Look up whether the file path that's associated with the token is a file or
// directory and call ResolveDragDropTokenWithFileType with the result. // directory and call ResolveDragDropTokenWithFileType with the result.
const base::FilePath& drag_drop_token_path = FileSystemURLAndFSHandle url = CreateFileSystemURLFromPath(
drag_token_impl->second->file_path(); binding_context.origin, drag_token_impl->second->path_type(),
base::ThreadPool::PostTaskAndReplyWithResult( drag_token_impl->second->file_path());
FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING}, auto fs_url = url.url;
base::BindOnce(&GetFileType, drag_drop_token_path), operation_runner().PostTaskWithThisObject(
FROM_HERE,
base::BindOnce( base::BindOnce(
&NativeFileSystemManagerImpl::ResolveDragDropTokenWithFileType, &GetHandleTypeFromUrl, fs_url,
weak_factory_.GetWeakPtr(), binding_context, drag_drop_token_path, base::BindOnce(
std::move(token_resolved_callback))); &NativeFileSystemManagerImpl::ResolveDragDropTokenWithFileType,
weak_factory_.GetWeakPtr(), binding_context,
drag_token_impl->second->file_path(), std::move(url),
std::move(token_resolved_callback)),
base::SequencedTaskRunnerHandle::Get()));
} }
void NativeFileSystemManagerImpl::ResolveDragDropTokenWithFileType( void NativeFileSystemManagerImpl::ResolveDragDropTokenWithFileType(
const BindingContext& binding_context, const BindingContext& binding_context,
const base::FilePath& file_path, const base::FilePath& file_path,
FileSystemURLAndFSHandle url,
GetEntryFromDragDropTokenCallback token_resolved_callback, GetEntryFromDragDropTokenCallback token_resolved_callback,
HandleType file_type) { HandleType file_type) {
SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
file_path, binding_context.origin, std::move(url.file_system), file_type,
UserAction::kDragAndDrop);
blink::mojom::NativeFileSystemEntryPtr entry; blink::mojom::NativeFileSystemEntryPtr entry;
// TODO(mek): Support Drag&Drop of non-local paths.
if (file_type == HandleType::kDirectory) { if (file_type == HandleType::kDirectory) {
entry = CreateDirectoryEntryFromPath(binding_context, PathType::kLocal, entry = blink::mojom::NativeFileSystemEntry::New(
file_path, UserAction::kDragAndDrop); blink::mojom::NativeFileSystemHandle::NewDirectory(
CreateDirectoryHandle(binding_context, url.url,
shared_handle_state)),
url.base_name);
} else { } else {
entry = CreateFileEntryFromPath(binding_context, PathType::kLocal, entry = blink::mojom::NativeFileSystemEntry::New(
file_path, UserAction::kDragAndDrop); blink::mojom::NativeFileSystemHandle::NewFile(
CreateFileHandle(binding_context, url.url, shared_handle_state)),
url.base_name);
} }
std::move(token_resolved_callback).Run(std::move(entry)); std::move(token_resolved_callback).Run(std::move(entry));
......
...@@ -171,6 +171,7 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl ...@@ -171,6 +171,7 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl
// associated remote can be redeemed for a NativeFileSystemEntry object by a // associated remote can be redeemed for a NativeFileSystemEntry object by a
// process with ID matching `renderer_id`. // process with ID matching `renderer_id`.
void CreateNativeFileSystemDragDropToken( void CreateNativeFileSystemDragDropToken(
PathType path_type,
const base::FilePath& file_path, const base::FilePath& file_path,
int renderer_id, int renderer_id,
mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken> mojo::PendingReceiver<blink::mojom::NativeFileSystemDragDropToken>
...@@ -307,6 +308,7 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl ...@@ -307,6 +308,7 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl
void ResolveDragDropTokenWithFileType( void ResolveDragDropTokenWithFileType(
const BindingContext& binding_context, const BindingContext& binding_context,
const base::FilePath& file_path, const base::FilePath& file_path,
FileSystemURLAndFSHandle url,
GetEntryFromDragDropTokenCallback token_resolved_callback, GetEntryFromDragDropTokenCallback token_resolved_callback,
NativeFileSystemPermissionContext::HandleType file_type); NativeFileSystemPermissionContext::HandleType file_type);
......
...@@ -216,6 +216,117 @@ class NativeFileSystemManagerImplTest : public testing::Test { ...@@ -216,6 +216,117 @@ class NativeFileSystemManagerImplTest : public testing::Test {
return result; return result;
} }
void GetEntryFromDropTokenFileTest(
const base::FilePath& file_path,
NativeFileSystemEntryFactory::PathType path_type,
const std::string& expected_file_contents) {
// Create a token representing a dropped file at `file_path`.
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken>
token_remote;
manager_->CreateNativeFileSystemDragDropToken(
path_type, file_path, kBindingContext.process_id(),
token_remote.InitWithNewPipeAndPassReceiver());
// Expect permission requests when the token is sent to be redeemed.
EXPECT_CALL(
permission_context_,
GetReadPermissionGrant(
kTestOrigin, file_path, HandleType::kFile,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
EXPECT_CALL(
permission_context_,
GetWritePermissionGrant(
kTestOrigin, file_path, HandleType::kFile,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
// Attempt to resolve `token_remote` and store the resulting
// NativeFileSystemFileHandle in `file_remote`.
base::RunLoop await_token_resolution;
blink::mojom::NativeFileSystemEntryPtr native_file_system_entry;
manager_remote_->GetEntryFromDragDropToken(
std::move(token_remote),
base::BindLambdaForTesting([&](blink::mojom::NativeFileSystemEntryPtr
returned_native_file_system_entry) {
native_file_system_entry =
std::move(returned_native_file_system_entry);
await_token_resolution.Quit();
}));
await_token_resolution.Run();
ASSERT_FALSE(native_file_system_entry.is_null());
ASSERT_TRUE(native_file_system_entry->entry_handle->is_file());
mojo::Remote<blink::mojom::NativeFileSystemFileHandle> file_handle(
std::move(native_file_system_entry->entry_handle->get_file()));
// Check to see if the resulting NativeFileSystemFileHandle can read the
// contents of the file at `file_path`.
EXPECT_EQ(ReadStringFromFileRemote(std::move(file_handle)),
expected_file_contents);
}
void GetEntryFromDropTokenDirectoryTest(
const base::FilePath& dir_path,
NativeFileSystemEntryFactory::PathType path_type,
const std::string& expected_child_file_name) {
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken>
token_remote;
manager_->CreateNativeFileSystemDragDropToken(
path_type, dir_path, kBindingContext.process_id(),
token_remote.InitWithNewPipeAndPassReceiver());
// Expect permission requests when the token is sent to be redeemed.
EXPECT_CALL(
permission_context_,
GetReadPermissionGrant(
kTestOrigin, dir_path, HandleType::kDirectory,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
EXPECT_CALL(
permission_context_,
GetWritePermissionGrant(
kTestOrigin, dir_path, HandleType::kDirectory,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
// Attempt to resolve `token_remote` and store the resulting
// NativeFileSystemDirectoryHandle in `dir_remote`.
base::RunLoop await_token_resolution;
blink::mojom::NativeFileSystemEntryPtr native_file_system_entry;
manager_remote_->GetEntryFromDragDropToken(
std::move(token_remote),
base::BindLambdaForTesting([&](blink::mojom::NativeFileSystemEntryPtr
returned_native_file_system_entry) {
native_file_system_entry =
std::move(returned_native_file_system_entry);
await_token_resolution.Quit();
}));
await_token_resolution.Run();
ASSERT_FALSE(native_file_system_entry.is_null());
ASSERT_TRUE(native_file_system_entry->entry_handle->is_directory());
mojo::Remote<blink::mojom::NativeFileSystemDirectoryHandle> dir_remote(
std::move(native_file_system_entry->entry_handle->get_directory()));
// Use `dir_remote` to verify that dir_path contains a child called
// expected_child_file_name.
base::RunLoop await_get_file;
dir_remote->GetFile(
expected_child_file_name, /*create=*/false,
base::BindLambdaForTesting(
[&](blink::mojom::NativeFileSystemErrorPtr result,
mojo::PendingRemote<blink::mojom::NativeFileSystemFileHandle>
file_handle) {
await_get_file.Quit();
ASSERT_EQ(blink::mojom::NativeFileSystemStatus::kOk,
result->status);
}));
await_get_file.Run();
}
protected: protected:
const GURL kTestURL = GURL("https://example.com/test"); const GURL kTestURL = GURL("https://example.com/test");
const url::Origin kTestOrigin = url::Origin::Create(kTestURL); const url::Origin kTestOrigin = url::Origin::Create(kTestURL);
...@@ -745,51 +856,12 @@ TEST_F(NativeFileSystemManagerImplTest, SerializeHandle_ExternalFile) { ...@@ -745,51 +856,12 @@ TEST_F(NativeFileSystemManagerImplTest, SerializeHandle_ExternalFile) {
TEST_F(NativeFileSystemManagerImplTest, TEST_F(NativeFileSystemManagerImplTest,
GetEntryFromDragDropToken_File_ValidPID) { GetEntryFromDragDropToken_File_ValidPID) {
// Create a file and write some text into it. // Create a file and write some text into it.
base::FilePath file_path = dir_.GetPath().AppendASCII("mr_file"); const base::FilePath file_path = dir_.GetPath().AppendASCII("mr_file");
const std::string file_contents = "Deleted code is debugged code."; const std::string file_contents = "Deleted code is debugged code.";
ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
ASSERT_TRUE(base::WriteFile(file_path, file_contents)); ASSERT_TRUE(base::WriteFile(file_path, file_contents));
// Create a token representing a dropped file at `file_path`. GetEntryFromDropTokenFileTest(
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote; file_path, NativeFileSystemEntryFactory::PathType::kLocal, file_contents);
manager_->CreateNativeFileSystemDragDropToken(
file_path, kBindingContext.process_id(),
token_remote.InitWithNewPipeAndPassReceiver());
// Expect permission requests when the token is sent to be redeemed.
EXPECT_CALL(permission_context_,
GetReadPermissionGrant(
kTestOrigin, file_path, HandleType::kFile,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
EXPECT_CALL(permission_context_,
GetWritePermissionGrant(
kTestOrigin, file_path, HandleType::kFile,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
// Attempt to resolve `token_remote` and store the resulting
// NativeFileSystemFileHandle in `file_remote`.
base::RunLoop await_token_resolution;
blink::mojom::NativeFileSystemEntryPtr native_file_system_entry;
manager_remote_->GetEntryFromDragDropToken(
std::move(token_remote),
base::BindLambdaForTesting([&](blink::mojom::NativeFileSystemEntryPtr
returned_native_file_system_entry) {
native_file_system_entry = std::move(returned_native_file_system_entry);
await_token_resolution.Quit();
}));
await_token_resolution.Run();
ASSERT_FALSE(native_file_system_entry.is_null());
ASSERT_TRUE(native_file_system_entry->entry_handle->is_file());
mojo::Remote<blink::mojom::NativeFileSystemFileHandle> file_handle(
std::move(native_file_system_entry->entry_handle->get_file()));
// Check to see if the resulting NativeFileSystemFileHandle can read the
// contents of the file at `file_path`.
EXPECT_EQ(ReadStringFromFileRemote(std::move(file_handle)), file_contents);
} }
// NativeFileSystemManager should successfully resolve a // NativeFileSystemManager should successfully resolve a
...@@ -800,63 +872,56 @@ TEST_F(NativeFileSystemManagerImplTest, ...@@ -800,63 +872,56 @@ TEST_F(NativeFileSystemManagerImplTest,
GetEntryFromDragDropToken_Directory_ValidPID) { GetEntryFromDragDropToken_Directory_ValidPID) {
// Create a directory and create a NativeFileSystemDragDropToken representing // Create a directory and create a NativeFileSystemDragDropToken representing
// the new directory. // the new directory.
const base::FilePath kDirPath = dir_.GetPath().AppendASCII("mr_dir"); const base::FilePath dir_path = dir_.GetPath().AppendASCII("mr_dir");
ASSERT_TRUE(base::CreateDirectory(kDirPath)); ASSERT_TRUE(base::CreateDirectory(dir_path));
const std::string child_file_name = "child-file-name.txt";
ASSERT_TRUE(base::WriteFile(dir_path.AppendASCII(child_file_name), ""));
GetEntryFromDropTokenDirectoryTest(
dir_path, NativeFileSystemEntryFactory::PathType::kLocal,
child_file_name);
}
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote; // NativeFileSystemManager should successfully resolve a
manager_->CreateNativeFileSystemDragDropToken( // NativeFileSystemDragDropToken representing a file in the user's file system
kDirPath, kBindingContext.process_id(), // into a valid Remote<blink::mojom::NativeFileSystemFileHandle>, given
token_remote.InitWithNewPipeAndPassReceiver()); // that the PID is valid.
TEST_F(NativeFileSystemManagerImplTest,
GetEntryFromDragDropToken_File_ExternalPath) {
// Create a file and write some text into it.
const base::FilePath file_path = dir_.GetPath().AppendASCII("mr_file");
const std::string file_contents = "Deleted code is debugged code.";
ASSERT_TRUE(base::WriteFile(file_path, file_contents));
// Expect permission requests when the token is sent to be redeemed. const base::FilePath virtual_file_path =
EXPECT_CALL(permission_context_, base::FilePath::FromUTF8Unsafe(kTestMountPoint)
GetReadPermissionGrant( .Append(file_path.BaseName());
kTestOrigin, kDirPath, HandleType::kDirectory,
NativeFileSystemPermissionContext::UserAction::kDragAndDrop))
.WillOnce(testing::Return(allow_grant_));
EXPECT_CALL(permission_context_, GetEntryFromDropTokenFileTest(
GetWritePermissionGrant( virtual_file_path, NativeFileSystemEntryFactory::PathType::kExternal,
kTestOrigin, kDirPath, HandleType::kDirectory, file_contents);
NativeFileSystemPermissionContext::UserAction::kDragAndDrop)) }
.WillOnce(testing::Return(allow_grant_));
// Attempt to resolve `token_remote` and store the resulting // NativeFileSystemManager should successfully resolve a
// NativeFileSystemDirectoryHandle in `dir_remote`. // NativeFileSystemDragDropToken representing a NativeFileSystemDirectoryEntry
base::RunLoop await_token_resolution; // into a valid Remote<blink::mojom::NativeFileSystemDirectoryHandle>, given
blink::mojom::NativeFileSystemEntryPtr native_file_system_entry; // that the PID is valid.
manager_remote_->GetEntryFromDragDropToken( TEST_F(NativeFileSystemManagerImplTest,
std::move(token_remote), GetEntryFromDragDropToken_Directory_ExternalPath) {
base::BindLambdaForTesting([&](blink::mojom::NativeFileSystemEntryPtr // Create a directory and create a NativeFileSystemDragDropToken representing
returned_native_file_system_entry) { // the new directory.
native_file_system_entry = std::move(returned_native_file_system_entry); const base::FilePath dir_path = dir_.GetPath().AppendASCII("mr_dir");
await_token_resolution.Quit(); ASSERT_TRUE(base::CreateDirectory(dir_path));
})); const std::string child_file_name = "child-file-name.txt";
await_token_resolution.Run(); ASSERT_TRUE(base::WriteFile(dir_path.AppendASCII(child_file_name), ""));
ASSERT_FALSE(native_file_system_entry.is_null()); const base::FilePath virtual_dir_path =
ASSERT_TRUE(native_file_system_entry->entry_handle->is_directory()); base::FilePath::FromUTF8Unsafe(kTestMountPoint)
mojo::Remote<blink::mojom::NativeFileSystemDirectoryHandle> dir_remote( .Append(dir_path.BaseName());
std::move(native_file_system_entry->entry_handle->get_directory()));
GetEntryFromDropTokenDirectoryTest(
// Use `dir_remote` to create a child of the directory, and pass the test if virtual_dir_path, NativeFileSystemEntryFactory::PathType::kExternal,
// the child was successfully created at the expected path. Block until this child_file_name);
// happens or test times out.
base::RunLoop await_get_directory;
const std::string kChildDirectory = "child_dir";
dir_remote->GetDirectory(
kChildDirectory, /*create=*/true,
base::BindLambdaForTesting(
[&](blink::mojom::NativeFileSystemErrorPtr result,
mojo::PendingRemote<blink::mojom::NativeFileSystemDirectoryHandle>
directory_handle) {
await_get_directory.Quit();
ASSERT_EQ(blink::mojom::NativeFileSystemStatus::kOk,
result->status);
EXPECT_TRUE(
kDirPath.IsParent(kDirPath.AppendASCII(kChildDirectory)));
}));
await_get_directory.Run();
} }
// NativeFileSystemManager should refuse to resolve a // NativeFileSystemManager should refuse to resolve a
...@@ -872,7 +937,8 @@ TEST_F(NativeFileSystemManagerImplTest, ...@@ -872,7 +937,8 @@ TEST_F(NativeFileSystemManagerImplTest,
// process attempting to redeem to the token. // process attempting to redeem to the token.
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote; mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote;
manager_->CreateNativeFileSystemDragDropToken( manager_->CreateNativeFileSystemDragDropToken(
file_path, /*renderer_id=*/kBindingContext.process_id() - 1, NativeFileSystemEntryFactory::PathType::kLocal, file_path,
/*renderer_id=*/kBindingContext.process_id() - 1,
token_remote.InitWithNewPipeAndPassReceiver()); token_remote.InitWithNewPipeAndPassReceiver());
// Try to redeem the NativeFileSystemDragDropToken for a // Try to redeem the NativeFileSystemDragDropToken for a
...@@ -897,7 +963,8 @@ TEST_F(NativeFileSystemManagerImplTest, ...@@ -897,7 +963,8 @@ TEST_F(NativeFileSystemManagerImplTest,
// process attempting to redeem to the token. // process attempting to redeem to the token.
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote; mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote;
manager_->CreateNativeFileSystemDragDropToken( manager_->CreateNativeFileSystemDragDropToken(
kDirPath, /*renderer_id=*/kBindingContext.process_id() - 1, NativeFileSystemEntryFactory::PathType::kLocal, kDirPath,
/*renderer_id=*/kBindingContext.process_id() - 1,
token_remote.InitWithNewPipeAndPassReceiver()); token_remote.InitWithNewPipeAndPassReceiver());
// Try to redeem the NativeFileSystemDragDropToken for a // Try to redeem the NativeFileSystemDragDropToken for a
...@@ -922,7 +989,8 @@ TEST_F(NativeFileSystemManagerImplTest, ...@@ -922,7 +989,8 @@ TEST_F(NativeFileSystemManagerImplTest,
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote; mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> token_remote;
auto drag_drop_token_impl = auto drag_drop_token_impl =
std::make_unique<NativeFileSystemDragDropTokenImpl>( std::make_unique<NativeFileSystemDragDropTokenImpl>(
manager_.get(), kDirPath, kBindingContext.process_id(), manager_.get(), NativeFileSystemEntryFactory::PathType::kLocal,
kDirPath, kBindingContext.process_id(),
token_remote.InitWithNewPipeAndPassReceiver()); token_remote.InitWithNewPipeAndPassReceiver());
// Try to redeem the NativeFileSystemDragDropToken for a // Try to redeem the NativeFileSystemDragDropToken for a
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "content/public/common/drop_data.h" #include "content/public/common/drop_data.h"
#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h"
#include "storage/browser/file_system/external_mount_points.h"
#include "third_party/blink/public/mojom/file_system_access/native_file_system_drag_drop_token.mojom.h" #include "third_party/blink/public/mojom/file_system_access/native_file_system_drag_drop_token.mojom.h"
#include "third_party/blink/public/mojom/page/drag.mojom.h" #include "third_party/blink/public/mojom/page/drag.mojom.h"
#include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/clipboard/clipboard_constants.h"
...@@ -22,6 +23,29 @@ ...@@ -22,6 +23,29 @@
namespace content { namespace content {
namespace {
// On Chrome OS paths that exist on an external mount point need to be treated
// differently to make sure the native file system code accesses these paths via
// the correct file system backend. This method checks if this is the case, and
// updates `entry_path` to the path that should be used by the native file
// system implementation.
content::NativeFileSystemEntryFactory::PathType MaybeRemapPath(
base::FilePath* entry_path) {
#if defined(OS_CHROMEOS)
base::FilePath virtual_path;
auto* external_mount_points =
storage::ExternalMountPoints::GetSystemInstance();
if (external_mount_points->GetVirtualPath(*entry_path, &virtual_path)) {
*entry_path = std::move(virtual_path);
return content::NativeFileSystemEntryFactory::PathType::kExternal;
}
#endif
return content::NativeFileSystemEntryFactory::PathType::kLocal;
}
} // namespace
blink::mojom::DragDataPtr DropDataToDragData( blink::mojom::DragDataPtr DropDataToDragData(
const DropData& drop_data, const DropData& drop_data,
NativeFileSystemManagerImpl* native_file_system_manager, NativeFileSystemManagerImpl* native_file_system_manager,
...@@ -56,11 +80,17 @@ blink::mojom::DragDataPtr DropDataToDragData( ...@@ -56,11 +80,17 @@ blink::mojom::DragDataPtr DropDataToDragData(
blink::mojom::DragItemFilePtr item = blink::mojom::DragItemFile::New(); blink::mojom::DragItemFilePtr item = blink::mojom::DragItemFile::New();
item->path = file.path; item->path = file.path;
item->display_name = file.display_name; item->display_name = file.display_name;
mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken> mojo::PendingRemote<blink::mojom::NativeFileSystemDragDropToken>
pending_token; pending_token;
base::FilePath entry_path = file.path;
NativeFileSystemManagerImpl::PathType path_type =
MaybeRemapPath(&entry_path);
native_file_system_manager->CreateNativeFileSystemDragDropToken( native_file_system_manager->CreateNativeFileSystemDragDropToken(
file.path, child_id, pending_token.InitWithNewPipeAndPassReceiver()); path_type, entry_path, child_id,
pending_token.InitWithNewPipeAndPassReceiver());
item->native_file_system_token = std::move(pending_token); item->native_file_system_token = std::move(pending_token);
items.push_back(blink::mojom::DragItem::NewFile(std::move(item))); items.push_back(blink::mojom::DragItem::NewFile(std::move(item)));
} }
for (const content::DropData::FileSystemFileInfo& file_system_file : for (const content::DropData::FileSystemFileInfo& file_system_file :
......
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