Commit 1a576289 authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

[FS] Go through file system abstraction for truncating files.

The save file dialog needs to truncate any files that are opened. Before
this was using base::File directly. This CL routes truncating through
the file system backends to facilitate supporting non-local files.

Bug: 1093653
Change-Id: I51c2cf8a776de70375e57be7a8a5d02641226bfa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2392414
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805501}
parent 1b4e3724
...@@ -117,10 +117,50 @@ void ShowFilePickerOnUIThread(const url::Origin& requesting_origin, ...@@ -117,10 +117,50 @@ void ShowFilePickerOnUIThread(const url::Origin& requesting_origin,
std::move(fullscreen_block)); std::move(fullscreen_block));
} }
bool CreateOrTruncateFile(const base::FilePath& path) { // Called after creating a file that was picked by a save file picker. If
int creation_flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE; // creation succeeded (or the file already existed) this will attempt to
base::File file(path, creation_flags); // truncate the file to zero bytes, and call `callback` on `reply_runner`
return file.IsValid(); // with the result of this operation.
void DidCreateFileToTruncate(
storage::FileSystemURL url,
base::OnceCallback<void(bool)> callback,
scoped_refptr<base::SequencedTaskRunner> reply_runner,
storage::FileSystemOperationRunner* operation_runner,
base::File::Error result) {
if (result != base::File::FILE_OK) {
// Failed to create the file, don't even try to truncate it.
reply_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), false));
return;
}
operation_runner->Truncate(
url, /*length=*/0,
base::BindOnce(
[](base::OnceCallback<void(bool)> callback,
scoped_refptr<base::SequencedTaskRunner> reply_runner,
base::File::Error result) {
reply_runner->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
result == base::File::FILE_OK));
},
std::move(callback), std::move(reply_runner)));
}
// Creates and truncates the file at `url`. Calls `callback` on `reply_runner`
// with true if this succeeded, or false if either creation or truncation
// failed.
void CreateAndTruncateFile(
storage::FileSystemURL url,
base::OnceCallback<void(bool)> callback,
scoped_refptr<base::SequencedTaskRunner> reply_runner,
storage::FileSystemOperationRunner* operation_runner) {
// Binding operation_runner as a raw pointer is safe, since the callback is
// invoked by the operation runner, and thus won't be invoked if the operation
// runner has been destroyed.
operation_runner->CreateFile(
url, /*exclusive=*/false,
base::BindOnce(&DidCreateFileToTruncate, url, std::move(callback),
std::move(reply_runner), operation_runner));
} }
bool IsValidTransferToken(NativeFileSystemTransferTokenImpl* token, bool IsValidTransferToken(NativeFileSystemTransferTokenImpl* token,
...@@ -845,12 +885,19 @@ void NativeFileSystemManagerImpl::DidVerifySensitiveDirectoryAccess( ...@@ -845,12 +885,19 @@ void NativeFileSystemManagerImpl::DidVerifySensitiveDirectoryAccess(
if (options.type() == blink::mojom::ChooseFileSystemEntryType::kSaveFile) { if (options.type() == blink::mojom::ChooseFileSystemEntryType::kSaveFile) {
DCHECK_EQ(entries.size(), 1u); DCHECK_EQ(entries.size(), 1u);
// Create file if it doesn't yet exist, and truncate file if it does exist. // Create file if it doesn't yet exist, and truncate file if it does exist.
base::ThreadPool::PostTaskAndReplyWithResult( FileSystemURLAndFSHandle url =
FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, CreateFileSystemURLFromPath(binding_context.origin, entries.front());
base::BindOnce(&CreateOrTruncateFile, entries.front()),
auto fs_url = url.url;
operation_runner().PostTaskWithThisObject(
FROM_HERE,
base::BindOnce( base::BindOnce(
&NativeFileSystemManagerImpl::DidCreateOrTruncateSaveFile, this, &CreateAndTruncateFile, fs_url,
binding_context, entries.front(), std::move(callback))); base::BindOnce(
&NativeFileSystemManagerImpl::DidCreateAndTruncateSaveFile,
this, binding_context, entries.front(), std::move(url),
std::move(callback)),
base::SequencedTaskRunnerHandle::Get()));
return; return;
} }
...@@ -864,14 +911,18 @@ void NativeFileSystemManagerImpl::DidVerifySensitiveDirectoryAccess( ...@@ -864,14 +911,18 @@ void NativeFileSystemManagerImpl::DidVerifySensitiveDirectoryAccess(
std::move(result_entries)); std::move(result_entries));
} }
void NativeFileSystemManagerImpl::DidCreateOrTruncateSaveFile( void NativeFileSystemManagerImpl::DidCreateAndTruncateSaveFile(
const BindingContext& binding_context, const BindingContext& binding_context,
const base::FilePath& path, const base::FilePath& path,
FileSystemURLAndFSHandle url,
ChooseEntriesCallback callback, ChooseEntriesCallback callback,
bool success) { bool success) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::vector<blink::mojom::NativeFileSystemEntryPtr> result_entries; std::vector<blink::mojom::NativeFileSystemEntryPtr> result_entries;
if (!success) { if (!success) {
// TODO(https://crbug.com/1124871): Failure to create or truncate the file
// should probably not just result in a generic error, but instead inform
// the user of the problem?
std::move(callback).Run( std::move(callback).Run(
native_file_system_error::FromStatus( native_file_system_error::FromStatus(
blink::mojom::NativeFileSystemStatus::kOperationFailed, blink::mojom::NativeFileSystemStatus::kOperationFailed,
...@@ -879,8 +930,16 @@ void NativeFileSystemManagerImpl::DidCreateOrTruncateSaveFile( ...@@ -879,8 +930,16 @@ void NativeFileSystemManagerImpl::DidCreateOrTruncateSaveFile(
std::move(result_entries)); std::move(result_entries));
return; return;
} }
result_entries.push_back(
CreateFileEntryFromPath(binding_context, path, UserAction::kSave)); SharedHandleState shared_handle_state = GetSharedHandleStateForPath(
path, binding_context.origin, std::move(url.file_system),
HandleType::kFile, NativeFileSystemPermissionContext::UserAction::kSave);
result_entries.push_back(blink::mojom::NativeFileSystemEntry::New(
blink::mojom::NativeFileSystemHandle::NewFile(
CreateFileHandle(binding_context, url.url, shared_handle_state)),
url.base_name));
std::move(callback).Run(native_file_system_error::Ok(), std::move(callback).Run(native_file_system_error::Ok(),
std::move(result_entries)); std::move(result_entries));
} }
......
...@@ -248,10 +248,11 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl ...@@ -248,10 +248,11 @@ class CONTENT_EXPORT NativeFileSystemManagerImpl
ChooseEntriesCallback callback, ChooseEntriesCallback callback,
std::vector<base::FilePath> entries, std::vector<base::FilePath> entries,
NativeFileSystemPermissionContext::SensitiveDirectoryResult result); NativeFileSystemPermissionContext::SensitiveDirectoryResult result);
void DidCreateOrTruncateSaveFile(const BindingContext& binding_context, void DidCreateAndTruncateSaveFile(const BindingContext& binding_context,
const base::FilePath& path, const base::FilePath& path,
ChooseEntriesCallback callback, FileSystemURLAndFSHandle url,
bool success); ChooseEntriesCallback callback,
bool success);
void DidChooseDirectory( void DidChooseDirectory(
const BindingContext& binding_context, const BindingContext& binding_context,
const base::FilePath& path, const base::FilePath& path,
......
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