| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // This file provides file system related API functions. |
| |
| #ifndef CHROME_BROWSER_ASH_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_ |
| #define CHROME_BROWSER_ASH_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/functional/callback_forward.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/types/expected.h" |
| #include "chrome/browser/ash/extensions/file_manager/logged_extension_function.h" |
| #include "chrome/browser/ash/file_manager/trash_info_validator.h" |
| #include "chrome/browser/ash/fileapi/recent_source.h" |
| #include "chrome/browser/ash/policy/dlp/dlp_files_controller_ash.h" |
| #include "chrome/common/extensions/api/file_manager_private.h" |
| #include "chromeos/ash/components/drivefs/mojom/drivefs.mojom-forward.h" |
| #include "components/drive/file_errors.h" |
| #include "extensions/browser/extension_function.h" |
| #include "extensions/browser/extension_function_histogram_value.h" |
| #include "services/device/public/mojom/mtp_storage_info.mojom-forward.h" |
| #include "storage/browser/file_system/file_system_url.h" |
| |
| class Profile; |
| |
| namespace storage { |
| class FileSystemContext; |
| class FileSystemURL; |
| class WatcherManager; |
| } // namespace storage |
| |
| namespace file_manager { |
| class EventRouter; |
| namespace util { |
| struct EntryDefinition; |
| using EntryDefinitionList = std::vector<EntryDefinition>; |
| } // namespace util |
| } // namespace file_manager |
| |
| namespace drive::policy { |
| class DlpFilesControllerAsh; |
| } // namespace drive::policy |
| |
| namespace extensions { |
| |
| // Grant permission to request externalfile scheme. The permission is needed to |
| // start drag for external file URL. |
| class FileManagerPrivateEnableExternalFileSchemeFunction |
| : public ExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.enableExternalFileScheme", |
| FILEMANAGERPRIVATE_ENABLEEXTERNALFILESCHEME) |
| |
| protected: |
| ~FileManagerPrivateEnableExternalFileSchemeFunction() override = default; |
| |
| private: |
| ExtensionFunction::ResponseAction Run() override; |
| }; |
| |
| // Grants R/W permissions to profile-specific directories (Drive, Downloads) |
| // from other profiles. |
| class FileManagerPrivateGrantAccessFunction : public ExtensionFunction { |
| public: |
| FileManagerPrivateGrantAccessFunction(); |
| |
| FileManagerPrivateGrantAccessFunction( |
| const FileManagerPrivateGrantAccessFunction&) = delete; |
| FileManagerPrivateGrantAccessFunction& operator=( |
| const FileManagerPrivateGrantAccessFunction&) = delete; |
| |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.grantAccess", |
| FILEMANAGERPRIVATE_GRANTACCESS) |
| |
| protected: |
| ~FileManagerPrivateGrantAccessFunction() override = default; |
| |
| private: |
| ExtensionFunction::ResponseAction Run() override; |
| }; |
| |
| // Base class for FileManagerPrivateInternalAddFileWatchFunction and |
| // FileManagerPrivateInternalRemoveFileWatchFunction. Although it's called |
| // "FileWatch", |
| // the class and its sub classes are used only for watching changes in |
| // directories. |
| class FileWatchFunctionBase : public LoggedExtensionFunction { |
| public: |
| using ResponseCallback = base::OnceCallback<void(bool success)>; |
| |
| // Calls Respond() with |success| converted to base::Value. |
| void RespondWith(bool success); |
| |
| protected: |
| ~FileWatchFunctionBase() override = default; |
| |
| // A virtual method to tell the base class if the function is addFileWatch(). |
| virtual bool IsAddWatch() = 0; |
| |
| // Performs a file watch operation (ex. adds or removes a file watch) on |
| // the IO thread with storage::WatcherManager. |
| virtual void PerformFileWatchOperationOnIOThread( |
| scoped_refptr<storage::FileSystemContext> file_system_context, |
| storage::WatcherManager* watcher_manager, |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router) = 0; |
| |
| // Performs a file watch operation (ex. adds or removes a file watch) on |
| // the UI thread with file_manager::EventRouter. This is a fallback operation |
| // called only when WatcherManager is unavailable. |
| virtual void PerformFallbackFileWatchOperationOnUIThread( |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router) = 0; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| |
| private: |
| void RunAsyncOnIOThread( |
| scoped_refptr<storage::FileSystemContext> file_system_context, |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router); |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.addFileWatch method. |
| // Starts watching changes in directories. |
| class FileManagerPrivateInternalAddFileWatchFunction |
| : public FileWatchFunctionBase { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.addFileWatch", |
| FILEMANAGERPRIVATEINTERNAL_ADDFILEWATCH) |
| |
| protected: |
| ~FileManagerPrivateInternalAddFileWatchFunction() override = default; |
| |
| // FileWatchFunctionBase override. |
| void PerformFileWatchOperationOnIOThread( |
| scoped_refptr<storage::FileSystemContext> file_system_context, |
| storage::WatcherManager* watcher_manager, |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router) override; |
| void PerformFallbackFileWatchOperationOnUIThread( |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router) override; |
| bool IsAddWatch() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.removeFileWatch method. |
| // Stops watching changes in directories. |
| class FileManagerPrivateInternalRemoveFileWatchFunction |
| : public FileWatchFunctionBase { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.removeFileWatch", |
| FILEMANAGERPRIVATEINTERNAL_REMOVEFILEWATCH) |
| |
| protected: |
| ~FileManagerPrivateInternalRemoveFileWatchFunction() override = default; |
| |
| // FileWatchFunctionBase override. |
| void PerformFileWatchOperationOnIOThread( |
| scoped_refptr<storage::FileSystemContext> file_system_context, |
| storage::WatcherManager* watcher_manager, |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router) override; |
| void PerformFallbackFileWatchOperationOnUIThread( |
| const storage::FileSystemURL& file_system_url, |
| base::WeakPtr<file_manager::EventRouter> event_router) override; |
| bool IsAddWatch() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.getSizeStats method. |
| class FileManagerPrivateGetSizeStatsFunction : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getSizeStats", |
| FILEMANAGERPRIVATE_GETSIZESTATS) |
| |
| protected: |
| ~FileManagerPrivateGetSizeStatsFunction() override = default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| |
| private: |
| void OnGetMtpAvailableSpace(device::mojom::MtpStorageInfoPtr mtp_storage_info, |
| const bool error); |
| |
| void OnGetDocumentsProviderAvailableSpace(const bool error, |
| const uint64_t available_bytes, |
| const uint64_t capacity_bytes); |
| |
| void OnGetDriveQuotaUsage(drive::FileError error, |
| drivefs::mojom::QuotaUsagePtr usage); |
| |
| void OnGetSizeStats(const uint64_t* total_size, |
| const uint64_t* remaining_size); |
| }; |
| |
| // Implements the chrome.fileManagerPrivateInternal.getDriveQuotaMetadata |
| // method. |
| class FileManagerPrivateInternalGetDriveQuotaMetadataFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.getDriveQuotaMetadata", |
| FILEMANAGERPRIVATE_GETDRIVEQUOTAMETADATA) |
| |
| protected: |
| ~FileManagerPrivateInternalGetDriveQuotaMetadataFunction() override = default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| |
| private: |
| void OnGetPooledQuotaUsage(drive::FileError error, |
| drivefs::mojom::PooledQuotaUsagePtr usage); |
| void OnGetMetadata(drive::FileError error, |
| drivefs::mojom::FileMetadataPtr metadata); |
| |
| storage::FileSystemURL file_system_url_; |
| api::file_manager_private::DriveQuotaMetadata quotaMetadata_; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.validatePathNameLength method. |
| class FileManagerPrivateInternalValidatePathNameLengthFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION( |
| "fileManagerPrivateInternal.validatePathNameLength", |
| FILEMANAGERPRIVATEINTERNAL_VALIDATEPATHNAMELENGTH) |
| |
| protected: |
| ~FileManagerPrivateInternalValidatePathNameLengthFunction() override = |
| default; |
| |
| void OnFilePathLimitRetrieved(size_t current_length, size_t max_length); |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.formatVolume method. |
| // Formats Volume given its mount path. |
| class FileManagerPrivateFormatVolumeFunction : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.formatVolume", |
| FILEMANAGERPRIVATE_FORMATVOLUME) |
| |
| protected: |
| ~FileManagerPrivateFormatVolumeFunction() override = default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.singlePartitionFormat method. |
| // Deletes removable device partitions, create a single partition and format. |
| class FileManagerPrivateSinglePartitionFormatFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.singlePartitionFormat", |
| FILEMANAGERPRIVATE_SINGLEPARTITIONFORMAT) |
| |
| protected: |
| ~FileManagerPrivateSinglePartitionFormatFunction() override = default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.renameVolume method. |
| // Renames Volume given its mount path and new Volume name. |
| class FileManagerPrivateRenameVolumeFunction : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.renameVolume", |
| FILEMANAGERPRIVATE_RENAMEVOLUME) |
| |
| protected: |
| ~FileManagerPrivateRenameVolumeFunction() override = default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.getDisallowedTransfers method. |
| class FileManagerPrivateInternalGetDisallowedTransfersFunction |
| : public LoggedExtensionFunction { |
| public: |
| FileManagerPrivateInternalGetDisallowedTransfersFunction(); |
| |
| DECLARE_EXTENSION_FUNCTION( |
| "fileManagerPrivateInternal.getDisallowedTransfers", |
| FILEMANAGERPRIVATEINTERNAL_GETDISALLOWEDTRANSFERS) |
| |
| protected: |
| ~FileManagerPrivateInternalGetDisallowedTransfersFunction() override; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| |
| private: |
| void OnGetDisallowedFiles( |
| std::vector<storage::FileSystemURL> disallowed_files); |
| void OnConvertFileDefinitionListToEntryDefinitionList( |
| std::unique_ptr<file_manager::util::EntryDefinitionList> |
| entry_definition_list); |
| |
| raw_ptr<Profile> profile_ = nullptr; |
| |
| std::vector<storage::FileSystemURL> source_urls_; |
| storage::FileSystemURL destination_url_; |
| }; |
| |
| // Implements the chrome.fileManagerPrivateInternal.getDlpMetadata method. |
| class FileManagerPrivateInternalGetDlpMetadataFunction |
| : public LoggedExtensionFunction { |
| public: |
| FileManagerPrivateInternalGetDlpMetadataFunction(); |
| |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.getDlpMetadata", |
| FILEMANAGERPRIVATEINTERNAL_GETDLPMETADATA) |
| |
| protected: |
| ~FileManagerPrivateInternalGetDlpMetadataFunction() override; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| |
| private: |
| void OnGetDlpMetadata( |
| std::vector<policy::DlpFilesControllerAsh::DlpFileMetadata> dlp_metadata); |
| |
| std::vector<storage::FileSystemURL> source_urls_; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.getDlpRestrictionDetails method. |
| class FileManagerPrivateGetDlpRestrictionDetailsFunction |
| : public LoggedExtensionFunction { |
| public: |
| FileManagerPrivateGetDlpRestrictionDetailsFunction(); |
| |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getDlpRestrictionDetails", |
| FILEMANAGERPRIVATE_GETDLPRESTRICTIONDETAILS) |
| |
| protected: |
| ~FileManagerPrivateGetDlpRestrictionDetailsFunction() override; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.getDlpBlockedComponents method. |
| class FileManagerPrivateGetDlpBlockedComponentsFunction |
| : public LoggedExtensionFunction { |
| public: |
| FileManagerPrivateGetDlpBlockedComponentsFunction(); |
| |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getDlpBlockedComponents", |
| FILEMANAGERPRIVATE_GETDLPBLOCKEDCOMPONENTS) |
| |
| protected: |
| ~FileManagerPrivateGetDlpBlockedComponentsFunction() override; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.getDialogCaller method. |
| class FileManagerPrivateGetDialogCallerFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.getDialogCaller", |
| FILEMANAGERPRIVATE_GETDIALOGCALLER) |
| |
| protected: |
| ~FileManagerPrivateGetDialogCallerFunction() override = default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivateInternal.resolveIsolatedEntries |
| // method. |
| class FileManagerPrivateInternalResolveIsolatedEntriesFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION( |
| "fileManagerPrivateInternal.resolveIsolatedEntries", |
| FILEMANAGERPRIVATE_RESOLVEISOLATEDENTRIES) |
| |
| protected: |
| ~FileManagerPrivateInternalResolveIsolatedEntriesFunction() override = |
| default; |
| |
| // ExtensionFunction overrides. |
| ResponseAction Run() override; |
| |
| private: |
| void RunAsyncAfterConvertFileDefinitionListToEntryDefinitionList( |
| std::unique_ptr<file_manager::util::EntryDefinitionList> |
| entry_definition_list); |
| }; |
| |
| class FileManagerPrivateInternalSearchFilesFunction |
| : public LoggedExtensionFunction { |
| public: |
| // The type for matched files. The second element of the pair indicates if the |
| // path is that of a directory (true) or a plain file (false). |
| using FileSearchResults = std::vector<std::pair<base::FilePath, bool>>; |
| |
| // A callback on which the results are to be delivered. The results are |
| // expected to be delivered in a single invocation. |
| using OnResultsReadyCallback = base::OnceCallback<void(FileSearchResults)>; |
| |
| FileManagerPrivateInternalSearchFilesFunction(); |
| |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.searchFiles", |
| FILEMANAGERPRIVATEINTERNAL_SEARCHFILES) |
| |
| protected: |
| ~FileManagerPrivateInternalSearchFilesFunction() override = default; |
| |
| private: |
| // ExtensionFunction overrides. The launch point of search by name |
| // and search image by keywords. |
| ResponseAction Run() override; |
| |
| // Runs the search files by file name task. Once done invokes the callback. |
| // The root_path is the path to the top level directory which is to be |
| // searched. Only results from this directory and nested directories are |
| // accepted. |
| void RunFileSearchByName(Profile* profile, |
| base::FilePath root_path, |
| const std::string& query, |
| base::Time modified_time, |
| ash::RecentSource::FileType file_type, |
| size_t max_results, |
| OnResultsReadyCallback callback); |
| |
| // Runs the search images by query task. Once done invokes the callback. |
| // The root_path is the path to the top level directory which is to be |
| // searched. Only results from this directory and nested directories are |
| // accepted. |
| void RunImageSearchByQuery(base::FilePath root_path, |
| const std::string& query, |
| base::Time modified_time, |
| size_t max_results, |
| OnResultsReadyCallback callback); |
| |
| void OnSearchByPatternDone(std::vector<FileSearchResults> results); |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.getDirectorySize method. |
| class FileManagerPrivateInternalGetDirectorySizeFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.getDirectorySize", |
| FILEMANAGERPRIVATEINTERNAL_GETDIRECTORYSIZE) |
| |
| protected: |
| ~FileManagerPrivateInternalGetDirectorySizeFunction() override = default; |
| |
| void OnDirectorySizeRetrieved(int64_t size); |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.startIOTask method. |
| class FileManagerPrivateInternalStartIOTaskFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.startIOTask", |
| FILEMANAGERPRIVATEINTERNAL_STARTIOTASK) |
| |
| protected: |
| ~FileManagerPrivateInternalStartIOTaskFunction() override = default; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.cancelIOTask method. |
| class FileManagerPrivateCancelIOTaskFunction : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.cancelIOTask", |
| FILEMANAGERPRIVATE_CANCELIOTASK) |
| |
| protected: |
| ~FileManagerPrivateCancelIOTaskFunction() override = default; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.resumeIOTask method. |
| class FileManagerPrivateResumeIOTaskFunction : public ExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.resumeIOTask", |
| FILEMANAGERPRIVATE_RESUMEIOTASK) |
| |
| protected: |
| ~FileManagerPrivateResumeIOTaskFunction() override = default; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.dismissIOTask method. |
| class FileManagerPrivateDismissIOTaskFunction : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.dismissIOTask", |
| FILEMANAGERPRIVATE_DISMISSIOTASK) |
| |
| protected: |
| ~FileManagerPrivateDismissIOTaskFunction() override = default; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.progressPausedTasks method. |
| class FileManagerPrivateProgressPausedTasksFunction : public ExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.progressPausedTasks", |
| FILEMANAGERPRIVATE_PROGRESSPAUSEDTASKS) |
| |
| protected: |
| ~FileManagerPrivateProgressPausedTasksFunction() override = default; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| // Implements the chrome.fileManagerPrivate.showPolicyDialog method. |
| class FileManagerPrivateShowPolicyDialogFunction |
| : public LoggedExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivate.showPolicyDialog", |
| FILEMANAGERPRIVATE_SHOWPOLICYDIALOG) |
| |
| protected: |
| ~FileManagerPrivateShowPolicyDialogFunction() override = default; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| }; |
| |
| class FileManagerPrivateInternalParseTrashInfoFilesFunction |
| : public LoggedExtensionFunction { |
| public: |
| FileManagerPrivateInternalParseTrashInfoFilesFunction(); |
| |
| DECLARE_EXTENSION_FUNCTION("fileManagerPrivateInternal.parseTrashInfoFiles", |
| FILEMANAGERPRIVATEINTERNAL_PARSETRASHINFOFILES) |
| |
| protected: |
| ~FileManagerPrivateInternalParseTrashInfoFilesFunction() override; |
| |
| // ExtensionFunction overrides |
| ResponseAction Run() override; |
| |
| private: |
| // Invoked after calling the `ValidateAndParseTrashInfoFile` with all the data |
| // retrieved from the .trashinfo files. If any are error'd out they are logged |
| // and ultimately discarded. |
| void OnTrashInfoFilesParsed( |
| std::vector<file_manager::trash::ParsedTrashInfoDataOrError> parsed_data); |
| |
| // After converting the restorePath (converted to Entry to ensure we can |
| // perform a getMetadata on it to verify existence) zip the 2 `std::vector`'s |
| // together to return back to the UI. |
| void OnConvertFileDefinitionListToEntryDefinitionList( |
| std::vector<file_manager::trash::ParsedTrashInfoData> parsed_data, |
| std::unique_ptr<file_manager::util::EntryDefinitionList> |
| entry_definition_list); |
| |
| scoped_refptr<storage::FileSystemContext> file_system_context_; |
| |
| // The TrashInfoValidator that maintains a connection to the TrashService |
| // which performs the parsing. |
| std::unique_ptr<file_manager::trash::TrashInfoValidator> validator_ = nullptr; |
| }; |
| |
| } // namespace extensions |
| |
| #endif // CHROME_BROWSER_ASH_EXTENSIONS_FILE_MANAGER_PRIVATE_API_FILE_SYSTEM_H_ |