Index: chrome/browser/chromeos/file_system_provider/service.cc |
diff --git a/chrome/browser/chromeos/file_system_provider/service.cc b/chrome/browser/chromeos/file_system_provider/service.cc |
deleted file mode 100644 |
index faa6ce5c885e84dfd936f31b30180fbcfade88a8..0000000000000000000000000000000000000000 |
--- a/chrome/browser/chromeos/file_system_provider/service.cc |
+++ /dev/null |
@@ -1,461 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/chromeos/file_system_provider/service.h" |
- |
-#include "base/files/file_path.h" |
-#include "base/prefs/pref_service.h" |
-#include "base/prefs/scoped_user_pref_update.h" |
-#include "base/stl_util.h" |
-#include "base/values.h" |
-#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" |
-#include "chrome/browser/chromeos/file_system_provider/observer.h" |
-#include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" |
-#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h" |
-#include "chrome/browser/chromeos/file_system_provider/registry.h" |
-#include "chrome/browser/chromeos/file_system_provider/registry_interface.h" |
-#include "chrome/browser/chromeos/file_system_provider/service_factory.h" |
-#include "chrome/browser/chromeos/file_system_provider/throttled_file_system.h" |
-#include "extensions/browser/event_router.h" |
-#include "extensions/browser/extension_registry.h" |
-#include "extensions/browser/extension_system.h" |
-#include "extensions/common/permissions/api_permission.h" |
-#include "extensions/common/permissions/permissions_data.h" |
-#include "storage/browser/fileapi/external_mount_points.h" |
-#include "storage/common/fileapi/file_system_mount_option.h" |
- |
-namespace chromeos { |
-namespace file_system_provider { |
-namespace { |
- |
-// Maximum number of file systems to be mounted in the same time, per profile. |
-const size_t kMaxFileSystems = 16; |
- |
-// Default factory for provided file systems. |profile| must not be NULL. |
-ProvidedFileSystemInterface* CreateProvidedFileSystem( |
- Profile* profile, |
- const ProvidedFileSystemInfo& file_system_info) { |
- DCHECK(profile); |
- return new ThrottledFileSystem( |
- make_scoped_ptr(new ProvidedFileSystem(profile, file_system_info))); |
-} |
- |
-} // namespace |
- |
-ProvidingExtensionInfo::ProvidingExtensionInfo() { |
-} |
- |
-ProvidingExtensionInfo::~ProvidingExtensionInfo() { |
-} |
- |
-Service::Service(Profile* profile, |
- extensions::ExtensionRegistry* extension_registry) |
- : profile_(profile), |
- extension_registry_(extension_registry), |
- file_system_factory_(base::Bind(&CreateProvidedFileSystem)), |
- registry_(new Registry(profile)), |
- weak_ptr_factory_(this) { |
- extension_registry_->AddObserver(this); |
-} |
- |
-Service::~Service() { |
- extension_registry_->RemoveObserver(this); |
- |
- // Provided file systems should be already unmounted because of receiving |
- // OnExtensionUnload calls for each installed extension. However, for tests |
- // we may still have mounted extensions. |
- // TODO(mtomasz): Create a TestingService class and remove this code. |
- ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
- while (it != file_system_map_.end()) { |
- const std::string file_system_id = |
- it->second->GetFileSystemInfo().file_system_id(); |
- const std::string extension_id = |
- it->second->GetFileSystemInfo().extension_id(); |
- ++it; |
- const base::File::Error unmount_result = UnmountFileSystem( |
- extension_id, file_system_id, UNMOUNT_REASON_SHUTDOWN); |
- DCHECK_EQ(base::File::FILE_OK, unmount_result); |
- } |
- |
- DCHECK_EQ(0u, file_system_map_.size()); |
- STLDeleteValues(&file_system_map_); |
-} |
- |
-// static |
-Service* Service::Get(content::BrowserContext* context) { |
- return ServiceFactory::Get(context); |
-} |
- |
-void Service::AddObserver(Observer* observer) { |
- DCHECK(observer); |
- observers_.AddObserver(observer); |
-} |
- |
-void Service::RemoveObserver(Observer* observer) { |
- DCHECK(observer); |
- observers_.RemoveObserver(observer); |
-} |
- |
-void Service::SetFileSystemFactoryForTesting( |
- const FileSystemFactoryCallback& factory_callback) { |
- DCHECK(!factory_callback.is_null()); |
- file_system_factory_ = factory_callback; |
-} |
- |
-void Service::SetRegistryForTesting(scoped_ptr<RegistryInterface> registry) { |
- DCHECK(registry); |
- registry_.reset(registry.release()); |
-} |
- |
-base::File::Error Service::MountFileSystem(const std::string& extension_id, |
- const MountOptions& options) { |
- return MountFileSystemInternal(extension_id, options, MOUNT_CONTEXT_USER); |
-} |
- |
-base::File::Error Service::MountFileSystemInternal( |
- const std::string& extension_id, |
- const MountOptions& options, |
- MountContext context) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- // If already exists a file system provided by the same extension with this |
- // id, then abort. |
- if (GetProvidedFileSystem(extension_id, options.file_system_id)) { |
- FOR_EACH_OBSERVER( |
- Observer, observers_, |
- OnProvidedFileSystemMount(ProvidedFileSystemInfo(), context, |
- base::File::FILE_ERROR_EXISTS)); |
- return base::File::FILE_ERROR_EXISTS; |
- } |
- |
- // Restrict number of file systems to prevent system abusing. |
- if (file_system_map_.size() + 1 > kMaxFileSystems) { |
- FOR_EACH_OBSERVER( |
- Observer, observers_, |
- OnProvidedFileSystemMount(ProvidedFileSystemInfo(), context, |
- base::File::FILE_ERROR_TOO_MANY_OPENED)); |
- return base::File::FILE_ERROR_TOO_MANY_OPENED; |
- } |
- |
- storage::ExternalMountPoints* const mount_points = |
- storage::ExternalMountPoints::GetSystemInstance(); |
- DCHECK(mount_points); |
- |
- // The mount point path and name are unique per system, since they are system |
- // wide. This is necessary for copying between profiles. |
- const base::FilePath& mount_path = |
- util::GetMountPath(profile_, extension_id, options.file_system_id); |
- const std::string mount_point_name = mount_path.BaseName().AsUTF8Unsafe(); |
- |
- if (!mount_points->RegisterFileSystem( |
- mount_point_name, storage::kFileSystemTypeProvided, |
- storage::FileSystemMountOption( |
- storage::FlushPolicy::FLUSH_ON_COMPLETION), |
- mount_path)) { |
- FOR_EACH_OBSERVER( |
- Observer, observers_, |
- OnProvidedFileSystemMount(ProvidedFileSystemInfo(), context, |
- base::File::FILE_ERROR_INVALID_OPERATION)); |
- return base::File::FILE_ERROR_INVALID_OPERATION; |
- } |
- |
- ProvidingExtensionInfo provider_info; |
- // TODO(mtomasz): Set up a testing extension in unit tests. |
- GetProvidingExtensionInfo(extension_id, &provider_info); |
- // Store the file system descriptor. Use the mount point name as the file |
- // system provider file system id. |
- // Examples: |
- // file_system_id = hello_world |
- // mount_point_name = b33f1337-hello_world-5aa5 |
- // writable = false |
- // supports_notify_tag = false |
- // mount_path = /provided/b33f1337-hello_world-5aa5 |
- // configurable = true |
- // source = SOURCE_FILE |
- ProvidedFileSystemInfo file_system_info( |
- extension_id, options, mount_path, |
- provider_info.capabilities.configurable(), |
- provider_info.capabilities.source()); |
- |
- ProvidedFileSystemInterface* file_system = |
- file_system_factory_.Run(profile_, file_system_info); |
- DCHECK(file_system); |
- file_system_map_[FileSystemKey(extension_id, options.file_system_id)] = |
- file_system; |
- mount_point_name_to_key_map_[mount_point_name] = |
- FileSystemKey(extension_id, options.file_system_id); |
- registry_->RememberFileSystem(file_system_info, *file_system->GetWatchers()); |
- |
- FOR_EACH_OBSERVER(Observer, observers_, |
- OnProvidedFileSystemMount(file_system_info, context, |
- base::File::FILE_OK)); |
- |
- return base::File::FILE_OK; |
-} |
- |
-base::File::Error Service::UnmountFileSystem(const std::string& extension_id, |
- const std::string& file_system_id, |
- UnmountReason reason) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- const ProvidedFileSystemMap::iterator file_system_it = |
- file_system_map_.find(FileSystemKey(extension_id, file_system_id)); |
- if (file_system_it == file_system_map_.end()) { |
- const ProvidedFileSystemInfo empty_file_system_info; |
- FOR_EACH_OBSERVER( |
- Observer, |
- observers_, |
- OnProvidedFileSystemUnmount(empty_file_system_info, |
- base::File::FILE_ERROR_NOT_FOUND)); |
- return base::File::FILE_ERROR_NOT_FOUND; |
- } |
- |
- storage::ExternalMountPoints* const mount_points = |
- storage::ExternalMountPoints::GetSystemInstance(); |
- DCHECK(mount_points); |
- |
- const ProvidedFileSystemInfo& file_system_info = |
- file_system_it->second->GetFileSystemInfo(); |
- |
- const std::string mount_point_name = |
- file_system_info.mount_path().BaseName().value(); |
- if (!mount_points->RevokeFileSystem(mount_point_name)) { |
- FOR_EACH_OBSERVER( |
- Observer, |
- observers_, |
- OnProvidedFileSystemUnmount(file_system_info, |
- base::File::FILE_ERROR_INVALID_OPERATION)); |
- return base::File::FILE_ERROR_INVALID_OPERATION; |
- } |
- |
- FOR_EACH_OBSERVER( |
- Observer, |
- observers_, |
- OnProvidedFileSystemUnmount(file_system_info, base::File::FILE_OK)); |
- |
- mount_point_name_to_key_map_.erase(mount_point_name); |
- |
- if (reason == UNMOUNT_REASON_USER) { |
- registry_->ForgetFileSystem(file_system_info.extension_id(), |
- file_system_info.file_system_id()); |
- } |
- |
- delete file_system_it->second; |
- file_system_map_.erase(file_system_it); |
- |
- return base::File::FILE_OK; |
-} |
- |
-bool Service::RequestUnmount(const std::string& extension_id, |
- const std::string& file_system_id) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- ProvidedFileSystemMap::iterator file_system_it = |
- file_system_map_.find(FileSystemKey(extension_id, file_system_id)); |
- if (file_system_it == file_system_map_.end()) |
- return false; |
- |
- file_system_it->second->RequestUnmount( |
- base::Bind(&Service::OnRequestUnmountStatus, |
- weak_ptr_factory_.GetWeakPtr(), |
- file_system_it->second->GetFileSystemInfo())); |
- return true; |
-} |
- |
-bool Service::RequestMount(const std::string& extension_id) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- extensions::EventRouter* const event_router = |
- extensions::EventRouter::Get(profile_); |
- DCHECK(event_router); |
- |
- if (!event_router->ExtensionHasEventListener( |
- extension_id, extensions::api::file_system_provider:: |
- OnMountRequested::kEventName)) { |
- return false; |
- } |
- |
- event_router->DispatchEventToExtension( |
- extension_id, |
- make_scoped_ptr(new extensions::Event( |
- extensions::api::file_system_provider::OnMountRequested::kEventName, |
- scoped_ptr<base::ListValue>(new base::ListValue())))); |
- |
- return true; |
-} |
- |
-std::vector<ProvidedFileSystemInfo> Service::GetProvidedFileSystemInfoList() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- std::vector<ProvidedFileSystemInfo> result; |
- for (ProvidedFileSystemMap::const_iterator it = file_system_map_.begin(); |
- it != file_system_map_.end(); |
- ++it) { |
- result.push_back(it->second->GetFileSystemInfo()); |
- } |
- return result; |
-} |
- |
-ProvidedFileSystemInterface* Service::GetProvidedFileSystem( |
- const std::string& extension_id, |
- const std::string& file_system_id) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- const ProvidedFileSystemMap::const_iterator file_system_it = |
- file_system_map_.find(FileSystemKey(extension_id, file_system_id)); |
- if (file_system_it == file_system_map_.end()) |
- return NULL; |
- |
- return file_system_it->second; |
-} |
- |
-std::vector<ProvidingExtensionInfo> Service::GetProvidingExtensionInfoList() |
- const { |
- extensions::ExtensionRegistry* const registry = |
- extensions::ExtensionRegistry::Get(profile_); |
- DCHECK(registry); |
- |
- std::vector<ProvidingExtensionInfo> result; |
- for (const auto& extension : registry->enabled_extensions()) { |
- ProvidingExtensionInfo info; |
- if (GetProvidingExtensionInfo(extension->id(), &info)) |
- result.push_back(info); |
- } |
- |
- return result; |
-} |
- |
-bool Service::GetProvidingExtensionInfo(const std::string& extension_id, |
- ProvidingExtensionInfo* result) const { |
- DCHECK(result); |
- extensions::ExtensionRegistry* const registry = |
- extensions::ExtensionRegistry::Get(profile_); |
- DCHECK(registry); |
- |
- const extensions::Extension* const extension = registry->GetExtensionById( |
- extension_id, extensions::ExtensionRegistry::ENABLED); |
- if (!extension || |
- !extension->permissions_data()->HasAPIPermission( |
- extensions::APIPermission::kFileSystemProvider)) { |
- return false; |
- } |
- |
- result->extension_id = extension->id(); |
- result->name = extension->name(); |
- const extensions::FileSystemProviderCapabilities* const capabilities = |
- extensions::FileSystemProviderCapabilities::Get(extension); |
- DCHECK(capabilities); |
- result->capabilities = *capabilities; |
- |
- return true; |
-} |
- |
-void Service::OnExtensionUnloaded( |
- content::BrowserContext* browser_context, |
- const extensions::Extension* extension, |
- extensions::UnloadedExtensionInfo::Reason reason) { |
- // Unmount all of the provided file systems associated with this extension. |
- ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
- while (it != file_system_map_.end()) { |
- const ProvidedFileSystemInfo& file_system_info = |
- it->second->GetFileSystemInfo(); |
- // Advance the iterator beforehand, otherwise it will become invalidated |
- // by the UnmountFileSystem() call. |
- ++it; |
- if (file_system_info.extension_id() == extension->id()) { |
- const base::File::Error unmount_result = UnmountFileSystem( |
- file_system_info.extension_id(), file_system_info.file_system_id(), |
- reason == extensions::UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN |
- ? UNMOUNT_REASON_SHUTDOWN |
- : UNMOUNT_REASON_USER); |
- DCHECK_EQ(base::File::FILE_OK, unmount_result); |
- } |
- } |
-} |
- |
-void Service::OnExtensionLoaded(content::BrowserContext* browser_context, |
- const extensions::Extension* extension) { |
- scoped_ptr<RegistryInterface::RestoredFileSystems> restored_file_systems = |
- registry_->RestoreFileSystems(extension->id()); |
- |
- for (const auto& restored_file_system : *restored_file_systems) { |
- const base::File::Error result = MountFileSystemInternal( |
- restored_file_system.extension_id, restored_file_system.options, |
- MOUNT_CONTEXT_RESTORE); |
- if (result != base::File::FILE_OK) { |
- LOG(ERROR) << "Failed to restore a provided file system from " |
- << "registry: " << restored_file_system.extension_id << ", " |
- << restored_file_system.options.file_system_id << ", " |
- << restored_file_system.options.display_name << "."; |
- // Since remounting of the file system failed, then remove it from |
- // preferences to avoid remounting it over and over again with a failure. |
- registry_->ForgetFileSystem(restored_file_system.extension_id, |
- restored_file_system.options.file_system_id); |
- continue; |
- } |
- |
- ProvidedFileSystemInterface* const file_system = |
- GetProvidedFileSystem(restored_file_system.extension_id, |
- restored_file_system.options.file_system_id); |
- DCHECK(file_system); |
- file_system->GetWatchers()->insert(restored_file_system.watchers.begin(), |
- restored_file_system.watchers.end()); |
- } |
-} |
- |
-ProvidedFileSystemInterface* Service::GetProvidedFileSystem( |
- const std::string& mount_point_name) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- const MountPointNameToKeyMap::const_iterator mapping_it = |
- mount_point_name_to_key_map_.find(mount_point_name); |
- if (mapping_it == mount_point_name_to_key_map_.end()) |
- return NULL; |
- |
- const ProvidedFileSystemMap::const_iterator file_system_it = |
- file_system_map_.find(mapping_it->second); |
- if (file_system_it == file_system_map_.end()) |
- return NULL; |
- |
- return file_system_it->second; |
-} |
- |
-void Service::OnRequestUnmountStatus( |
- const ProvidedFileSystemInfo& file_system_info, |
- base::File::Error error) { |
- // Notify observers about failure in unmounting, since mount() will not be |
- // called by the provided file system. In case of success mount() will be |
- // invoked, and observers notified, so there is no need to call them now. |
- if (error != base::File::FILE_OK) { |
- FOR_EACH_OBSERVER(Observer, |
- observers_, |
- OnProvidedFileSystemUnmount(file_system_info, error)); |
- } |
-} |
- |
-void Service::OnWatcherChanged(const ProvidedFileSystemInfo& file_system_info, |
- const Watcher& watcher, |
- storage::WatcherManager::ChangeType change_type, |
- const Changes& changes, |
- const base::Closure& callback) { |
- callback.Run(); |
-} |
- |
-void Service::OnWatcherTagUpdated( |
- const ProvidedFileSystemInfo& file_system_info, |
- const Watcher& watcher) { |
- PrefService* const pref_service = profile_->GetPrefs(); |
- DCHECK(pref_service); |
- |
- registry_->UpdateWatcherTag(file_system_info, watcher); |
-} |
- |
-void Service::OnWatcherListChanged( |
- const ProvidedFileSystemInfo& file_system_info, |
- const Watchers& watchers) { |
- registry_->RememberFileSystem(file_system_info, watchers); |
-} |
- |
-} // namespace file_system_provider |
-} // namespace chromeos |