Index: chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin_service.cc |
diff --git a/chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin_service.cc b/chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin_service.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6e55648e0b772508947083f147d39e4bf55c96d6 |
--- /dev/null |
+++ b/chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin_service.cc |
@@ -0,0 +1,249 @@ |
+// Copyright 2015 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/file_system_plugin/plugin_service.h" |
+ |
+#include "chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin_service_factory.h" |
+#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" |
+#include "chrome/browser/chromeos/file_system_provider/throttled_file_system.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 plugin filesystems |
+const size_t kMaxFileSystems = 16; |
+ |
+ProvidedFileSystemAdapter* CreateProvidedFileSystem( |
+ Profile* profile, |
+ const ProvidedFileSystemInfo& file_system_info) { |
+ DCHECK(profile); |
+ return new ProvidedFileSystemAdapter( |
+ make_scoped_ptr( |
+ new ThrottledFileSystem(make_scoped_ptr( |
+ new ProvidedFileSystem<PluginDestination>( |
+ profile, file_system_info))))); |
+} |
+ |
+} // namespace |
+ |
+PluginService::PluginService(Profile *profile) |
+ : profile_(profile), |
+ weak_ptr_factory_(this) { |
+} |
+ |
+PluginService::~PluginService() { |
+ // Remove any remaining plugin backend |
+ ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
+ while (it != file_system_map_.end()) { |
+ const std::string file_system_id = |
+ it->second->GetProvidedFileSystem()-> |
+ GetFileSystemInfo().file_system_id(); |
+ const std::string source_id = |
+ it->second->GetProvidedFileSystem()->GetFileSystemInfo().source_id(); |
+ ++it; |
+ const base::File::Error unmount_result = UnmountFileSystem( |
+ source_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 |
+PluginService* PluginService::Get(content::BrowserContext *context) { |
+ return PluginServiceFactory::Get(context); |
+} |
+ |
+void PluginService::AddObserver(Observer *observer) { |
+ DCHECK(observer); |
+ observers_.AddObserver(observer); |
+} |
+ |
+void PluginService::RemoveObserver(Observer *observer) { |
+ DCHECK(observer); |
+ observers_.RemoveObserver(observer); |
+} |
+ |
+ProvidedFileSystemAdapter*PluginService::GetProvidedFileSystemAdapter( |
+ const std::string& plugin_id, const std::string& file_system_id) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ const ProvidedFileSystemMap::const_iterator file_system_it = |
+ file_system_map_.find(FileSystemKey(plugin_id, file_system_id)); |
+ if (file_system_it == file_system_map_.end()) |
+ return NULL; |
+ |
+ return file_system_it->second; |
+} |
+ |
+ProvidedFileSystemInterface* PluginService::GetProvidedFileSystem( |
+ const std::string& source_id, |
+ const std::string& file_system_id) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ const ProvidedFileSystemMap::const_iterator file_system_it = |
+ file_system_map_.find(FileSystemKey(source_id, file_system_id)); |
+ if (file_system_it == file_system_map_.end()) |
+ return NULL; |
+ |
+ return file_system_it->second->GetProvidedFileSystem(); |
+} |
+ |
+ProvidedFileSystemInterface* PluginService::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->GetProvidedFileSystem(); |
+} |
+ |
+std::vector<ProvidedFileSystemInfo> |
+PluginService::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->GetProvidedFileSystem()->GetFileSystemInfo()); |
+ } |
+ return result; |
+} |
+ |
+base::File::Error PluginService::MountFileSystem( |
+ const std::string &source_id, const MountOptions &options) { |
+ return MountFileSystemInternal( source_id, options, MOUNT_CONTEXT_USER ); |
+} |
+ |
+base::File::Error PluginService::MountFileSystemInternal( |
+ const std::string& source_id, |
+ const MountOptions& options, MountContext context) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ // If already exists a file system provided by the same source with this |
+ // id, then abort. |
+ if (GetProvidedFileSystem(source_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); |
+ |
+ const base::FilePath& mount_path = util::GetPluginMountPath( |
+ profile_, source_id, options.file_system_id); |
+ const std::string mount_point_name = mount_path.BaseName().AsUTF8Unsafe(); |
+ |
+ if (!mount_points->RegisterFileSystem( |
+ mount_point_name, storage::kFileSystemTypePluginProvided, |
+ 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; |
+ } |
+ |
+ ProvidedFileSystemAdapter* file_system = NULL; |
+ ProvidedFileSystemInfo file_system_info = ProvidedFileSystemInfo( |
+ source_id, |
+ options, |
+ mount_path, |
+ false, |
+ extensions::SOURCE_NETWORK, |
+ Source_Type::plugin); |
+ file_system = CreateProvidedFileSystem(profile_, file_system_info); |
+ |
+ DCHECK(file_system); |
+ file_system_map_[FileSystemKey(source_id, options.file_system_id)] = |
+ file_system; |
+ mount_point_name_to_key_map_[mount_point_name] = |
+ FileSystemKey(source_id, options.file_system_id); |
+ |
+ |
+ FOR_EACH_OBSERVER(Observer, observers_, |
+ OnProvidedFileSystemMount(file_system_info, context, |
+ base::File::FILE_OK)); |
+ |
+ return base::File::FILE_OK; |
+} |
+ |
+base::File::Error PluginService::UnmountFileSystem( |
+ const std::string &source_id, |
+ const std::string &file_system_id, |
+ UnmountReason /*reason*/) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ const ProvidedFileSystemMap::iterator file_system_it = |
+ file_system_map_.find(FileSystemKey(source_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->GetProvidedFileSystem()->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); |
+ |
+ delete file_system_it->second; |
+ file_system_map_.erase(file_system_it); |
+ |
+ return base::File::FILE_OK; |
+} |
+ |
+} // namespace file_system_provider |
+} // namespace chromeos |
+ |