| 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
|
| +
|
|
|