1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_SERVICE_H_
#define CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_SERVICE_H_
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/files/file.h"
#include "base/functional/callback_helpers.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/threading/thread_checker.h"
#include "chrome/browser/ash/file_system_provider/content_cache/cache_manager.h"
#include "chrome/browser/ash/file_system_provider/extension_provider.h"
#include "chrome/browser/ash/file_system_provider/observer.h"
#include "chrome/browser/ash/file_system_provider/provided_file_system_info.h"
#include "chrome/browser/ash/file_system_provider/provided_file_system_interface.h"
#include "chrome/browser/ash/file_system_provider/provided_file_system_observer.h"
#include "chrome/browser/ash/file_system_provider/provider_interface.h"
#include "chrome/browser/ash/file_system_provider/watcher.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/file_system_provider.h"
#include "chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_id.h"
#include "storage/browser/file_system/watcher_manager.h"
namespace extensions {
class ExtensionRegistry;
} // namespace extensions
namespace user_prefs {
class PrefRegistrySyncable;
} // namespace user_prefs
namespace ash::file_system_provider {
class ProvidedFileSystemInfo;
class ProvidedFileSystemInterface;
class RegistryInterface;
struct MountOptions;
// Registers preferences to remember registered file systems between reboots.
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Manages and registers the file system provider service. Maintains provided
// file systems.
class Service : public KeyedService,
public extensions::ExtensionRegistryObserver,
public ProvidedFileSystemObserver {
public:
typedef std::map<ProviderId, std::unique_ptr<ProviderInterface>> ProviderMap;
// Reason for unmounting. In case of UNMOUNT_REASON_SHUTDOWN, the file system
// will be remounted automatically after a reboot. In case of
// UNMOUNT_REASON_USER it will be permanently unmounted.
enum UnmountReason { UNMOUNT_REASON_USER, UNMOUNT_REASON_SHUTDOWN };
Service(Profile* profile, extensions::ExtensionRegistry* extension_registry);
Service(const Service&) = delete;
Service& operator=(const Service&) = delete;
~Service() override;
// Gets the singleton instance for the |context|.
static Service* Get(content::BrowserContext* context);
// KeyedService:
void Shutdown() override;
// Sets a custom Registry implementation. Used by unit tests.
void SetRegistryForTesting(std::unique_ptr<RegistryInterface> registry);
// Mounts a file system provided by a provider with the |provider_id|. If
// |writable| is set to true, then the file system is mounted in a R/W mode.
// Otherwise, only read-only operations are supported. If change notification
// tags are supported, then |supports_notify_tag| must be true. Note, that
// it is required in order to enable the internal cache. For success, returns
// base::File::FILE_OK, otherwise an error code.
base::File::Error MountFileSystem(const ProviderId& provider_id,
const MountOptions& options);
// Unmounts a file system with the specified |file_system_id| for the
// |provider_id|. For success returns base::File::FILE_OK, otherwise an error
// code.
base::File::Error UnmountFileSystem(const ProviderId& provider_id,
const std::string& file_system_id,
UnmountReason reason);
// Requests unmounting of the file system. Returns false if the request could
// not been created, true otherwise.
bool RequestUnmount(const ProviderId& provider_id,
const std::string& file_system_id);
// Requests mounting a new file system by the providing extension with
// |provider_id|. Returns false if the request could not been created, true
// otherwise.
bool RequestMount(const ProviderId& provider_id,
RequestMountCallback callback);
// Returns a list of information of all currently provided file systems. All
// items are copied.
std::vector<ProvidedFileSystemInfo> GetProvidedFileSystemInfoList();
// Returns a list of information of the currently provided file systems for
// |provider_id|. All items are copied.
std::vector<ProvidedFileSystemInfo> GetProvidedFileSystemInfoList(
const ProviderId& provider_id);
// Returns a file system provider for the passed |provider_id|. If not found
// then returns nullptr.
ProviderInterface* GetProvider(const ProviderId& provider_id);
// Returns an immutable map of all registered providers.
const ProviderMap& GetProviders() const;
// Returns a provided file system with |file_system_id|, handled by
// the extension with |provider_id|. If not found, then returns NULL.
ProvidedFileSystemInterface* GetProvidedFileSystem(
const ProviderId& provider_id,
const std::string& file_system_id);
// Returns a provided file system attached to the the passed
// |mount_point_name|. If not found, then returns NULL.
ProvidedFileSystemInterface* GetProvidedFileSystem(
const std::string& mount_point_name);
// Adds and removes observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// extensions::ExtensionRegistryObserver overrides.
void OnExtensionUnloaded(content::BrowserContext* browser_context,
const extensions::Extension* extension,
extensions::UnloadedExtensionReason reason) override;
void OnExtensionLoaded(content::BrowserContext* browser_context,
const extensions::Extension* extension) override;
// ProvidedFileSystemInterface::Observer overrides.
void OnWatcherChanged(const ProvidedFileSystemInfo& file_system_info,
const Watcher& watcher,
storage::WatcherManager::ChangeType change_type,
const ProvidedFileSystemObserver::Changes& changes,
base::OnceClosure callback) override;
void OnWatcherTagUpdated(const ProvidedFileSystemInfo& file_system_info,
const Watcher& watcher) override;
void OnWatcherListChanged(const ProvidedFileSystemInfo& file_system_info,
const Watchers& watchers) override;
// Registers a provider. Restores all remembered mounts.
void RegisterProvider(std::unique_ptr<ProviderInterface> provider);
// Unregisters a provider. Unmounts all currently mounted file systems.
// If the reason is UNMOUNT_REASON_USER then they will not be automatically
// restored on the next registration.
void UnregisterProvider(const ProviderId& provider_id, UnmountReason reason);
private:
FRIEND_TEST_ALL_PREFIXES(FileSystemProviderServiceTest, RememberFileSystem);
// Key is a pair of an extension id and file system id, which makes it
// unique among the entire service instance.
using FileSystemKey = std::pair<std::string, std::string>;
// Mounts the file system in the specified context. See MountFileSystem() for
// more information.
base::File::Error MountFileSystemInternal(const ProviderId& provider_id,
const MountOptions& options,
MountContext context);
// Called when the providing extension accepts or refuses a unmount request.
// If |error| is equal to FILE_OK, then the request is accepted.
void OnRequestUnmountStatus(const ProvidedFileSystemInfo& file_system_info,
base::File::Error error);
// Remembers the file system in preferences, in order to remount after a
// reboot.
void RememberFileSystem(const ProvidedFileSystemInfo& file_system_info,
const Watchers& watchers);
// Removes the file system from preferences, so it is not remounted anymore
// after a reboot.
void ForgetFileSystem(const ProviderId& provider_id,
const std::string& file_system_id);
// Restores from preferences file systems mounted previously by the
// |provider_id| provided file system.
void RestoreFileSystems(const ProviderId& provider_id);
// Unmounts all currently mounted file systems for this provider. If
// reason is UNMOUNT_REASON_USER then the file systems will not be remembered
// for automagical remount in the future.
void UnmountFileSystems(const ProviderId& provider_id, UnmountReason reason);
raw_ptr<Profile> profile_;
raw_ptr<extensions::ExtensionRegistry> extension_registry_; // Not owned.
base::ObserverList<Observer>::Unchecked observers_;
std::map<FileSystemKey, std::unique_ptr<ProvidedFileSystemInterface>>
file_system_map_;
std::map<std::string, FileSystemKey> mount_point_name_to_key_map_;
std::unique_ptr<RegistryInterface> registry_;
std::unique_ptr<CacheManager> cache_manager_;
base::ThreadChecker thread_checker_;
ProviderMap provider_map_;
base::WeakPtrFactory<Service> weak_ptr_factory_{this};
};
} // namespace ash::file_system_provider
#endif // CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_SERVICE_H_
|