Compare commits

...

1 Commits

Author SHA1 Message Date
Shelley Vohr
8608d442e3 wip 2025-07-13 10:50:20 +02:00
4 changed files with 511 additions and 5 deletions

View File

@@ -13,12 +13,14 @@
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/containers/to_vector.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "chrome/browser/file_system_access/file_system_access_features.h"
#include "chrome/browser/predictors/preconnect_manager.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
@@ -106,6 +108,34 @@ namespace electron {
namespace {
bool DoesFileSystemAccessPermissionMatch(const base::Value& permission_grant,
const base::Value& grant_to_compare) {
if (!permission_grant.is_dict() || !grant_to_compare.is_dict()) {
return false;
}
const auto& grant_dict = permission_grant.GetDict();
const auto& compare_dict = grant_to_compare.GetDict();
// Compare file path
const auto* grant_path = grant_dict.FindString("path");
const auto* compare_path = compare_dict.FindString("path");
if (!grant_path || !compare_path || *grant_path != *compare_path) {
return false;
}
// Compare permission type (readable/writable)
const auto grant_readable = grant_dict.FindBool("readable").value_or(false);
const auto compare_readable =
compare_dict.FindBool("readable").value_or(false);
const auto grant_writable = grant_dict.FindBool("writable").value_or(false);
const auto compare_writable =
compare_dict.FindBool("writable").value_or(false);
return grant_readable == compare_readable &&
grant_writable == compare_writable;
}
// Copied from chrome/browser/media/webrtc/desktop_capture_devices_util.cc.
media::mojom::CaptureHandlePtr CreateCaptureHandle(
content::WebContents* capturer,
@@ -863,6 +893,94 @@ bool ElectronBrowserContext::CheckDevicePermission(
return false;
}
void ElectronBrowserContext::GrantFileSystemAccessPermission(
const url::Origin& origin,
const base::Value& permission_grant,
blink::PermissionType permission_type) {
if (!base::FeatureList::IsEnabled(
features::kFileSystemAccessPersistentPermissions)) {
return;
}
granted_devices_[permission_type][origin].push_back(
std::make_unique<base::Value>(permission_grant.Clone()));
}
void ElectronBrowserContext::RevokeFileSystemAccessPermission(
const url::Origin& origin,
const base::Value& permission_grant,
blink::PermissionType permission_type) {
if (!base::FeatureList::IsEnabled(
features::kFileSystemAccessPersistentPermissions)) {
return;
}
const auto& current_permissions_it = granted_devices_.find(permission_type);
if (current_permissions_it == granted_devices_.end())
return;
const auto& origin_permissions_it =
current_permissions_it->second.find(origin);
if (origin_permissions_it == current_permissions_it->second.end())
return;
std::erase_if(
origin_permissions_it->second, [&permission_grant](auto const& val) {
return DoesFileSystemAccessPermissionMatch(permission_grant, *val);
});
}
bool ElectronBrowserContext::CheckFileSystemAccessPermission(
const url::Origin& origin,
const base::Value& permission_grant,
blink::PermissionType permission_type) {
if (!base::FeatureList::IsEnabled(
features::kFileSystemAccessPersistentPermissions)) {
return false;
}
const auto& current_permissions_it = granted_devices_.find(permission_type);
if (current_permissions_it == granted_devices_.end())
return false;
const auto& origin_permissions_it =
current_permissions_it->second.find(origin);
if (origin_permissions_it == current_permissions_it->second.end())
return false;
for (const auto& grant_to_compare : origin_permissions_it->second) {
if (DoesFileSystemAccessPermissionMatch(permission_grant,
*grant_to_compare))
return true;
}
return false;
}
std::vector<base::Value>
ElectronBrowserContext::GetFileSystemAccessGrantsForOrigin(
const url::Origin& origin,
blink::PermissionType permission_type) {
std::vector<base::Value> grants;
if (!base::FeatureList::IsEnabled(
features::kFileSystemAccessPersistentPermissions)) {
return grants;
}
const auto& current_permissions_it = granted_devices_.find(permission_type);
if (current_permissions_it == granted_devices_.end())
return grants;
const auto& origin_permissions_it =
current_permissions_it->second.find(origin);
if (origin_permissions_it == current_permissions_it->second.end())
return grants;
for (const auto& grant : origin_permissions_it->second) {
grants.push_back(grant->Clone());
}
return grants;
}
// static
ElectronBrowserContext* ElectronBrowserContext::From(
const std::string& partition,

View File

@@ -159,6 +159,24 @@ class ElectronBrowserContext : public content::BrowserContext {
const base::Value& device,
blink::PermissionType permissionType);
// File System Access persistent permissions
void GrantFileSystemAccessPermission(const url::Origin& origin,
const base::Value& permission_grant,
blink::PermissionType permission_type);
void RevokeFileSystemAccessPermission(const url::Origin& origin,
const base::Value& permission_grant,
blink::PermissionType permission_type);
bool CheckFileSystemAccessPermission(const url::Origin& origin,
const base::Value& permission_grant,
blink::PermissionType permission_type);
// Get all file system access grants for an origin
std::vector<base::Value> GetFileSystemAccessGrantsForOrigin(
const url::Origin& origin,
blink::PermissionType permission_type);
private:
using DevicePermissionMap = std::map<
blink::PermissionType,

View File

@@ -9,6 +9,7 @@
#include <utility>
#include "base/base_paths.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/values_util.h"
@@ -32,6 +33,7 @@
#include "content/public/browser/web_contents.h"
#include "gin/data_object_builder.h"
#include "shell/browser/api/electron_api_session.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/browser/electron_permission_manager.h"
#include "shell/browser/web_contents_permission_helper.h"
#include "shell/common/gin_converters/callback_converter.h"
@@ -81,13 +83,21 @@ struct Converter<
namespace {
using BlockType = ChromeFileSystemAccessPermissionContext::BlockType;
using HandleType = content::FileSystemAccessPermissionContext::HandleType;
using GrantType = electron::FileSystemAccessPermissionContext::GrantType;
using BlockType = ChromeFileSystemAccessPermissionContext::BlockType;
using SensitiveEntryResult =
ChromeFileSystemAccessPermissionContext::SensitiveEntryResult;
using blink::mojom::PermissionStatus;
// Preference keys for persistent file system access grants
const char kPermissionPathKey[] = "path";
const char kPermissionDisplayNameKey[] = "display-name";
const char kPermissionIsDirectoryKey[] = "is-directory";
const char kPermissionWritableKey[] = "writable";
const char kPermissionReadableKey[] = "readable";
const char kPermissionGrantTimeKey[] = "grant-time";
// Dictionary keys for the FILE_SYSTEM_LAST_PICKED_DIRECTORY website setting.
// Schema (per origin):
// {
@@ -420,6 +430,10 @@ class FileSystemAccessPermissionContext::PermissionGrantImpl
if (status == blink::mojom::PermissionStatus::GRANTED) {
SetStatus(PermissionStatus::GRANTED);
// Save persistent grant when user grants permission
if (context_) {
context_->SavePersistedGrantsForOrigin(origin_);
}
std::move(callback).Run(PermissionRequestOutcome::kUserGranted);
} else {
SetStatus(PermissionStatus::DENIED);
@@ -456,6 +470,9 @@ struct FileSystemAccessPermissionContext::OriginState {
// PermissionGrantDestroyed().
std::map<base::FilePath, PermissionGrantImpl*> read_grants;
std::map<base::FilePath, PermissionGrantImpl*> write_grants;
// Persistent grant status for this origin
PersistedGrantStatus persisted_grant_status = PersistedGrantStatus::kLoaded;
};
FileSystemAccessPermissionContext::FileSystemAccessPermissionContext(
@@ -496,7 +513,14 @@ FileSystemAccessPermissionContext::GetReadPermissionGrant(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// operator[] might insert a new OriginState in |active_permissions_map_|,
// but that is exactly what we want.
bool is_new_origin = active_permissions_map_.find(origin) == active_permissions_map_.end();
auto& origin_state = active_permissions_map_[origin];
// Load persisted grants for new origins
if (is_new_origin) {
LoadPersistedGrantsForOrigin(origin);
}
auto*& existing_grant = origin_state.read_grants[path_info.path];
scoped_refptr<PermissionGrantImpl> grant;
@@ -523,6 +547,11 @@ FileSystemAccessPermissionContext::GetReadPermissionGrant(
if (creating_new_grant &&
AncestorHasActivePermission(origin, path_info.path, GrantType::kRead)) {
grant->SetStatus(PermissionStatus::GRANTED);
} else if (creating_new_grant &&
CanAutoGrantViaPersistentPermission(origin, path_info.path,
handle_type, GrantType::kRead)) {
// Check if we can auto-grant via persistent permissions
grant->SetStatus(PermissionStatus::GRANTED);
} else {
switch (user_action) {
case UserAction::kOpen:
@@ -554,7 +583,14 @@ FileSystemAccessPermissionContext::GetWritePermissionGrant(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// operator[] might insert a new OriginState in |active_permissions_map_|,
// but that is exactly what we want.
bool is_new_origin = active_permissions_map_.find(origin) == active_permissions_map_.end();
auto& origin_state = active_permissions_map_[origin];
// Load persisted grants for new origins
if (is_new_origin) {
LoadPersistedGrantsForOrigin(origin);
}
auto*& existing_grant = origin_state.write_grants[path_info.path];
scoped_refptr<PermissionGrantImpl> grant;
@@ -581,6 +617,11 @@ FileSystemAccessPermissionContext::GetWritePermissionGrant(
if (creating_new_grant &&
AncestorHasActivePermission(origin, path_info.path, GrantType::kWrite)) {
grant->SetStatus(PermissionStatus::GRANTED);
} else if (creating_new_grant &&
CanAutoGrantViaPersistentPermission(origin, path_info.path,
handle_type, GrantType::kWrite)) {
// Check if we can auto-grant via persistent permissions
grant->SetStatus(PermissionStatus::GRANTED);
} else {
switch (user_action) {
case UserAction::kSave:
@@ -830,7 +871,7 @@ content::PathInfo FileSystemAccessPermissionContext::GetLastPickedDirectory(
}
auto type_int = entry->FindInt(kPathTypeKey)
.value_or(static_cast<int>(content::PathType::kLocal));
.value_or(static_cast<int>(content::PathType::kExternal));
path_info.type = type_int == static_cast<int>(content::PathType::kExternal)
? content::PathType::kExternal
: content::PathType::kLocal;
@@ -968,7 +1009,6 @@ bool FileSystemAccessPermissionContext::OriginHasReadAccess(
return false;
}
bool FileSystemAccessPermissionContext::OriginHasWriteAccess(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -992,6 +1032,11 @@ void FileSystemAccessPermissionContext::NavigatedAwayFromOrigin(
return;
}
// Mark persistent grants as backgrounded when navigating away
if (it->second.persisted_grant_status == PersistedGrantStatus::kCurrent) {
SetPersistedGrantStatus(origin, PersistedGrantStatus::kBackgrounded);
}
// Start a timer to possibly clean up permissions for this origin.
if (!it->second.cleanup_timer) {
it->second.cleanup_timer = std::make_unique<base::RetainingOneShotTimer>(
@@ -1070,4 +1115,265 @@ FileSystemAccessPermissionContext::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace electron
// ============================================================================
// Persistent Permissions Implementation
//
// This implementation provides persistent file system access permissions that
// survive browser sessions. Unlike Chrome's ObjectPermissionContextBase
// approach, this uses Electron's preference system for storage.
//
// Key concepts:
// - PersistedGrantType: Represents the current state of persistent grants
// - kNone: No persistent grants exist
// - kDormant: Grants exist but are backgrounded
// - kActive: Grants are currently active
//
// - PersistedGrantStatus: Tracks origin-specific persistent state
// - kLoaded: Origin state loaded from preferences
// - kCurrent: Grants are active in current session
// - kBackgrounded: Grants exist but origin is backgrounded
//
// The implementation integrates with existing grant logic by:
// 1. Loading persisted grants when an origin first requests access
// 2. Checking persistent grants during auto-grant decisions
// 3. Saving grants when users approve permissions
// 4. Managing grant lifecycle during navigation events
// ============================================================================
FileSystemAccessPermissionContext::PersistedGrantType
FileSystemAccessPermissionContext::GetPersistedGrantType(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = active_permissions_map_.find(origin);
if (it == active_permissions_map_.end()) {
return PersistedGrantType::kNone;
}
switch (it->second.persisted_grant_status) {
case PersistedGrantStatus::kBackgrounded:
return PersistedGrantType::kDormant;
case PersistedGrantStatus::kLoaded:
case PersistedGrantStatus::kCurrent:
return PersistedGrantType::kActive;
}
}
FileSystemAccessPermissionContext::PersistedGrantStatus
FileSystemAccessPermissionContext::GetPersistedGrantStatus(
const url::Origin& origin) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = active_permissions_map_.find(origin);
if (it == active_permissions_map_.end()) {
return PersistedGrantStatus::kLoaded;
}
return it->second.persisted_grant_status;
}
void FileSystemAccessPermissionContext::SetPersistedGrantStatus(
const url::Origin& origin,
PersistedGrantStatus status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto& origin_state = active_permissions_map_[origin];
origin_state.persisted_grant_status = status;
}
void FileSystemAccessPermissionContext::LoadPersistedGrantsForOrigin(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto* browser_context = static_cast<ElectronBrowserContext*>(browser_context_);
// Load all file system grants for this origin
auto grants = browser_context->GetFileSystemAccessGrantsForOrigin(
origin, blink::PermissionType::FILE_SYSTEM);
// Create permission grants from persisted data
auto& origin_state = active_permissions_map_[origin];
for (const auto& grant_data : grants) {
if (auto* path_str = grant_data.GetDict().FindString(kPermissionPathKey)) {
base::FilePath path = base::FilePath::FromUTF8Unsafe(*path_str);
std::string display_name;
if (auto* display_name_val = grant_data.GetDict().FindString(kPermissionDisplayNameKey))
display_name = *display_name_val;
auto is_directory = grant_data.GetDict().FindBool(kPermissionIsDirectoryKey).value_or(false);
auto readable = grant_data.GetDict().FindBool(kPermissionReadableKey).value_or(false);
auto writable = grant_data.GetDict().FindBool(kPermissionWritableKey).value_or(false);
content::PathInfo path_info;
path_info.path = path;
path_info.display_name = display_name;
path_info.type = content::PathType::kLocal;
HandleType handle_type = is_directory ? HandleType::kDirectory : HandleType::kFile;
// Create read grant if readable
if (readable && origin_state.read_grants.find(path) == origin_state.read_grants.end()) {
auto grant = base::MakeRefCounted<PermissionGrantImpl>(
weak_factory_.GetWeakPtr(), origin, path_info, handle_type,
GrantType::kRead, UserAction::kLoadFromStorage);
grant->SetStatus(PermissionStatus::GRANTED);
origin_state.read_grants[path] = grant.get();
}
// Create write grant if writable
if (writable && origin_state.write_grants.find(path) == origin_state.write_grants.end()) {
auto grant = base::MakeRefCounted<PermissionGrantImpl>(
weak_factory_.GetWeakPtr(), origin, path_info, handle_type,
GrantType::kWrite, UserAction::kLoadFromStorage);
grant->SetStatus(PermissionStatus::GRANTED);
origin_state.write_grants[path] = grant.get();
}
}
}
SetPersistedGrantStatus(origin, PersistedGrantStatus::kLoaded);
}
void FileSystemAccessPermissionContext::SavePersistedGrantsForOrigin(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto* browser_context = static_cast<ElectronBrowserContext*>(browser_context_);
auto it = active_permissions_map_.find(origin);
if (it == active_permissions_map_.end()) {
return;
}
const auto& origin_state = it->second;
// Collect all unique paths and their permissions
std::map<base::FilePath, std::pair<bool, bool>> path_permissions; // path -> (readable, writable)
// Add read grants
for (const auto& [path, grant] : origin_state.read_grants) {
if (grant->GetStatus() == PermissionStatus::GRANTED) {
path_permissions[path].first = true;
}
}
// Add write grants
for (const auto& [path, grant] : origin_state.write_grants) {
if (grant->GetStatus() == PermissionStatus::GRANTED) {
path_permissions[path].second = true;
}
}
// Save combined grants
for (const auto& [path, permissions] : path_permissions) {
bool readable = permissions.first;
bool writable = permissions.second;
if (readable || writable) {
// Get grant info from either read or write grant
PermissionGrantImpl* grant = nullptr;
if (readable && origin_state.read_grants.count(path)) {
grant = origin_state.read_grants.at(path);
} else if (writable && origin_state.write_grants.count(path)) {
grant = origin_state.write_grants.at(path);
}
if (grant) {
base::Value::Dict grant_data;
grant_data.Set(kPermissionPathKey, path.AsUTF8Unsafe());
grant_data.Set(kPermissionDisplayNameKey, grant->GetDisplayName());
grant_data.Set(kPermissionIsDirectoryKey, grant->handle_type() == HandleType::kDirectory);
grant_data.Set(kPermissionReadableKey, readable);
grant_data.Set(kPermissionWritableKey, writable);
grant_data.Set(kPermissionGrantTimeKey, base::TimeToValue(clock_->Now()));
browser_context->GrantFileSystemAccessPermission(
origin, base::Value(std::move(grant_data)),
blink::PermissionType::FILE_SYSTEM);
}
}
}
SetPersistedGrantStatus(origin, PersistedGrantStatus::kCurrent);
}
bool FileSystemAccessPermissionContext::CanAutoGrantViaPersistentPermission(
const url::Origin& origin,
const base::FilePath& path,
HandleType handle_type,
GrantType grant_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Check if we have an active persistent permission for this path
auto persisted_grant_type = GetPersistedGrantType(origin);
if (persisted_grant_type == PersistedGrantType::kNone) {
return false;
}
auto* browser_context = static_cast<ElectronBrowserContext*>(browser_context_);
// Get all grants for this origin
auto grants = browser_context->GetFileSystemAccessGrantsForOrigin(
origin, blink::PermissionType::FILE_SYSTEM);
// Check if any grant matches our path and permission type
for (const auto& grant_data : grants) {
const auto& dict = grant_data.GetDict();
auto* stored_path = dict.FindString("path");
if (!stored_path || *stored_path != path.AsUTF8Unsafe()) {
continue;
}
auto stored_is_directory = dict.FindBool("is-directory").value_or(false);
bool handle_type_matches = (stored_is_directory && handle_type == HandleType::kDirectory) ||
(!stored_is_directory && handle_type == HandleType::kFile);
if (!handle_type_matches) {
continue;
}
bool readable = dict.FindBool("readable").value_or(false);
bool writable = dict.FindBool("writable").value_or(false);
if ((grant_type == GrantType::kRead && readable) ||
(grant_type == GrantType::kWrite && writable)) {
return true;
}
}
return false;
}
void FileSystemAccessPermissionContext::EnablePersistentPermissions(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
SetPersistedGrantStatus(origin, PersistedGrantStatus::kCurrent);
SavePersistedGrantsForOrigin(origin);
}
void FileSystemAccessPermissionContext::DisablePersistentPermissions(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto* browser_context = static_cast<ElectronBrowserContext*>(browser_context_);
// Get all existing grants and revoke them
auto grants = browser_context->GetFileSystemAccessGrantsForOrigin(
origin, blink::PermissionType::FILE_SYSTEM);
for (const auto& grant : grants) {
browser_context->RevokeFileSystemAccessPermission(
origin, grant, blink::PermissionType::FILE_SYSTEM);
}
SetPersistedGrantStatus(origin, PersistedGrantStatus::kLoaded);
}
bool FileSystemAccessPermissionContext::HasPersistentPermissions(
const url::Origin& origin) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto persisted_grant_type = GetPersistedGrantType(origin);
return persisted_grant_type != PersistedGrantType::kNone;
}
}

View File

@@ -20,7 +20,6 @@
#include "base/values.h"
#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h" // nogncheck
#include "components/keyed_service/core/keyed_service.h"
class GURL;
namespace gin {
@@ -37,12 +36,50 @@ class FileSystemURL;
namespace electron {
// FileSystemAccessPermissionContext provides file system access permission
// management for Electron applications. This implementation includes support
// for persistent permissions that survive browser sessions.
//
// Unlike Chrome's implementation which uses ObjectPermissionContextBase, this
// uses Electron's preference system for persistent storage, making it compatible
// with Electron's architecture.
//
// Key features:
// - Session-based grants for temporary permissions
// - Persistent grants that survive application restarts
// - Integration with Electron's permission system
// - Path blocklist checking and security restrictions
//
// Usage:
// - Call EnablePersistentPermissions() to enable persistent storage for an origin
// - Grants are automatically saved when users approve permissions
// - Grants are automatically loaded when origins access the file system
class FileSystemAccessPermissionContext
: public KeyedService,
public content::FileSystemAccessPermissionContext {
public:
enum class GrantType { kRead, kWrite };
// Represents persistent grant types for permissions
enum class PersistedGrantType {
// No persisted grants exist for this origin
kNone,
// Origin has persisted grants that are currently dormant (backgrounded)
kDormant,
// Origin has active persistent grants
kActive,
};
// Represents the origin-scoped state for persistent grants
enum class PersistedGrantStatus {
// Origin state has been loaded from preferences
kLoaded,
// Persisted grants are active for this session
kCurrent,
// Persisted grants are dormant due to being backgrounded
kBackgrounded
};
explicit FileSystemAccessPermissionContext(
content::BrowserContext* browser_context,
const base::Clock* clock = base::DefaultClock::GetInstance());
@@ -122,6 +159,15 @@ class FileSystemAccessPermissionContext
bool OriginHasReadAccess(const url::Origin& origin);
bool OriginHasWriteAccess(const url::Origin& origin);
// Enable persistent permissions for an origin
void EnablePersistentPermissions(const url::Origin& origin);
// Disable persistent permissions for an origin
void DisablePersistentPermissions(const url::Origin& origin);
// Check if an origin has persistent permissions enabled
bool HasPersistentPermissions(const url::Origin& origin);
// Called by FileSystemAccessWebContentsHelper when a top-level frame was
// navigated away from `origin` to some other origin.
void NavigatedAwayFromOrigin(const url::Origin& origin);
@@ -136,6 +182,24 @@ class FileSystemAccessPermissionContext
void PermissionGrantDestroyed(PermissionGrantImpl* grant);
// Persistent permissions methods
PersistedGrantType GetPersistedGrantType(const url::Origin& origin);
PersistedGrantStatus GetPersistedGrantStatus(const url::Origin& origin) const;
void SetPersistedGrantStatus(const url::Origin& origin,
PersistedGrantStatus status);
// Load persisted grants from preferences for an origin
void LoadPersistedGrantsForOrigin(const url::Origin& origin);
// Save current grants to preferences for an origin
void SavePersistedGrantsForOrigin(const url::Origin& origin);
// Check if a path can be auto-granted via persistent permissions
bool CanAutoGrantViaPersistentPermission(const url::Origin& origin,
const base::FilePath& path,
HandleType handle_type,
GrantType grant_type);
void CheckShouldBlockAccessToPathAndReply(
base::FilePath path,
HandleType handle_type,