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

[NativeFS] Make it possible to request read&write access at the same time.

When restoring a handle from IDB it won't be readable. If a website then
requests write access we need to prompt for both at the same time. This CL
implements this by removing a now invalid DCHECK in NativeFileSystemHandleBase
and adding support to NativeFileSystemPermissionRequestManager to combine
two requests into one prompt.

Bug: 984769
Change-Id: Ib1574c8142943adc412e7310505b63fc061f4557
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2092189
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: default avatarOlivier Yiptong <oyiptong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747991}
parent 2714fec9
...@@ -20,6 +20,13 @@ bool RequestsAreIdentical( ...@@ -20,6 +20,13 @@ bool RequestsAreIdentical(
a.is_directory == b.is_directory && a.access == b.access; a.is_directory == b.is_directory && a.access == b.access;
} }
bool RequestsAreForSamePath(
const NativeFileSystemPermissionRequestManager::RequestData& a,
const NativeFileSystemPermissionRequestManager::RequestData& b) {
return a.origin == b.origin && a.path == b.path &&
a.is_directory == b.is_directory;
}
} // namespace } // namespace
struct NativeFileSystemPermissionRequestManager::Request { struct NativeFileSystemPermissionRequestManager::Request {
...@@ -30,7 +37,7 @@ struct NativeFileSystemPermissionRequestManager::Request { ...@@ -30,7 +37,7 @@ struct NativeFileSystemPermissionRequestManager::Request {
callbacks.push_back(std::move(callback)); callbacks.push_back(std::move(callback));
} }
const RequestData data; RequestData data;
std::vector<base::OnceCallback<void(permissions::PermissionAction result)>> std::vector<base::OnceCallback<void(permissions::PermissionAction result)>>
callbacks; callbacks;
}; };
...@@ -57,6 +64,13 @@ void NativeFileSystemPermissionRequestManager::AddRequest( ...@@ -57,6 +64,13 @@ void NativeFileSystemPermissionRequestManager::AddRequest(
request->callbacks.push_back(std::move(callback)); request->callbacks.push_back(std::move(callback));
return; return;
} }
if (RequestsAreForSamePath(request->data, data)) {
// This means access levels are different. Change the existing request
// to kReadWrite, and add the new callback.
request->data.access = Access::kReadWrite;
request->callbacks.push_back(std::move(callback));
return;
}
} }
queued_requests_.push_back( queued_requests_.push_back(
......
...@@ -143,8 +143,10 @@ class OriginScopedNativeFileSystemPermissionContext::PermissionGrantImpl ...@@ -143,8 +143,10 @@ class OriginScopedNativeFileSystemPermissionContext::PermissionGrantImpl
? NativeFileSystemPermissionRequestManager::Access::kRead ? NativeFileSystemPermissionRequestManager::Access::kRead
: NativeFileSystemPermissionRequestManager::Access::kWrite; : NativeFileSystemPermissionRequestManager::Access::kWrite;
// TODO(mek): We need to somehow deal with the case where both read and // If a website wants both read and write access, code in content will
// write access are being asked for at the same time. // request those as two separate requests. The |request_manager| will then
// detect this and combine the two requests into one prompt. As such this
// code does not have to have any way to request Access::kReadWrite.
request_manager->AddRequest( request_manager->AddRequest(
{origin_, path_, is_directory_, access}, {origin_, path_, is_directory_, access},
......
...@@ -144,10 +144,16 @@ void NativeFileSystemHandleBase::DoRequestPermission( ...@@ -144,10 +144,16 @@ void NativeFileSystemHandleBase::DoRequestPermission(
return; return;
} }
// TODO(https://crbug.com/971401): Today we can't prompt for read permission, // Ask for both read and write permission at the same time, the permission
// and should never be in state "ASK". Since we already checked for DENIED // context should coalesce these into one prompt.
// above current status here should always be GRANTED. if (GetReadPermissionStatus() == PermissionStatus::ASK) {
DCHECK_EQ(GetReadPermissionStatus(), PermissionStatus::GRANTED); // Ignore callback for the read permission request; if the request fails,
// the write permission request probably fails the same way. And we check
// the final permission status after the permission request completes
// anyway.
handle_state_.read_grant->RequestPermission(
context().process_id, context().frame_id, base::DoNothing());
}
handle_state_.write_grant->RequestPermission( handle_state_.write_grant->RequestPermission(
context().process_id, context().frame_id, context().process_id, context().frame_id,
......
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