OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin
_service.h" |
| 6 |
| 7 #include "chrome/browser/chromeos/file_system_provider/file_system_plugin/plugin
_service_factory.h" |
| 8 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" |
| 9 #include "chrome/browser/chromeos/file_system_provider/throttled_file_system.h" |
| 10 #include "storage/browser/fileapi/external_mount_points.h" |
| 11 #include "storage/common/fileapi/file_system_mount_option.h" |
| 12 |
| 13 namespace chromeos { |
| 14 namespace file_system_provider { |
| 15 namespace { |
| 16 |
| 17 // Maximum number of plugin filesystems |
| 18 const size_t kMaxFileSystems = 16; |
| 19 |
| 20 ProvidedFileSystemAdapter* CreateProvidedFileSystem( |
| 21 Profile* profile, |
| 22 const ProvidedFileSystemInfo& file_system_info) { |
| 23 DCHECK(profile); |
| 24 return new ProvidedFileSystemAdapter( |
| 25 make_scoped_ptr( |
| 26 new ThrottledFileSystem(make_scoped_ptr( |
| 27 new ProvidedFileSystem<PluginDestination>( |
| 28 profile, file_system_info))))); |
| 29 } |
| 30 |
| 31 } // namespace |
| 32 |
| 33 PluginService::PluginService(Profile *profile) |
| 34 : profile_(profile), |
| 35 weak_ptr_factory_(this) { |
| 36 } |
| 37 |
| 38 PluginService::~PluginService() { |
| 39 // Remove any remaining plugin backend |
| 40 ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
| 41 while (it != file_system_map_.end()) { |
| 42 const std::string file_system_id = |
| 43 it->second->GetProvidedFileSystem()-> |
| 44 GetFileSystemInfo().file_system_id(); |
| 45 const std::string source_id = |
| 46 it->second->GetProvidedFileSystem()->GetFileSystemInfo().source_id(); |
| 47 ++it; |
| 48 const base::File::Error unmount_result = UnmountFileSystem( |
| 49 source_id, file_system_id, UNMOUNT_REASON_SHUTDOWN); |
| 50 DCHECK_EQ(base::File::FILE_OK, unmount_result); |
| 51 } |
| 52 |
| 53 DCHECK_EQ(0u, file_system_map_.size()); |
| 54 STLDeleteValues(&file_system_map_); |
| 55 } |
| 56 |
| 57 |
| 58 // static |
| 59 PluginService* PluginService::Get(content::BrowserContext *context) { |
| 60 return PluginServiceFactory::Get(context); |
| 61 } |
| 62 |
| 63 void PluginService::AddObserver(Observer *observer) { |
| 64 DCHECK(observer); |
| 65 observers_.AddObserver(observer); |
| 66 } |
| 67 |
| 68 void PluginService::RemoveObserver(Observer *observer) { |
| 69 DCHECK(observer); |
| 70 observers_.RemoveObserver(observer); |
| 71 } |
| 72 |
| 73 ProvidedFileSystemAdapter*PluginService::GetProvidedFileSystemAdapter( |
| 74 const std::string& plugin_id, const std::string& file_system_id) { |
| 75 DCHECK(thread_checker_.CalledOnValidThread()); |
| 76 const ProvidedFileSystemMap::const_iterator file_system_it = |
| 77 file_system_map_.find(FileSystemKey(plugin_id, file_system_id)); |
| 78 if (file_system_it == file_system_map_.end()) |
| 79 return NULL; |
| 80 |
| 81 return file_system_it->second; |
| 82 } |
| 83 |
| 84 ProvidedFileSystemInterface* PluginService::GetProvidedFileSystem( |
| 85 const std::string& source_id, |
| 86 const std::string& file_system_id) { |
| 87 DCHECK(thread_checker_.CalledOnValidThread()); |
| 88 |
| 89 const ProvidedFileSystemMap::const_iterator file_system_it = |
| 90 file_system_map_.find(FileSystemKey(source_id, file_system_id)); |
| 91 if (file_system_it == file_system_map_.end()) |
| 92 return NULL; |
| 93 |
| 94 return file_system_it->second->GetProvidedFileSystem(); |
| 95 } |
| 96 |
| 97 ProvidedFileSystemInterface* PluginService::GetProvidedFileSystem( |
| 98 const std::string& mount_point_name) { |
| 99 DCHECK(thread_checker_.CalledOnValidThread()); |
| 100 |
| 101 const MountPointNameToKeyMap::const_iterator mapping_it = |
| 102 mount_point_name_to_key_map_.find(mount_point_name); |
| 103 if (mapping_it == mount_point_name_to_key_map_.end()) |
| 104 return NULL; |
| 105 |
| 106 const ProvidedFileSystemMap::const_iterator file_system_it = |
| 107 file_system_map_.find(mapping_it->second); |
| 108 if (file_system_it == file_system_map_.end()) |
| 109 return NULL; |
| 110 |
| 111 return file_system_it->second->GetProvidedFileSystem(); |
| 112 } |
| 113 |
| 114 std::vector<ProvidedFileSystemInfo> |
| 115 PluginService::GetProvidedFileSystemInfoList() { |
| 116 DCHECK(thread_checker_.CalledOnValidThread()); |
| 117 |
| 118 std::vector<ProvidedFileSystemInfo> result; |
| 119 for (ProvidedFileSystemMap::const_iterator it = file_system_map_.begin(); |
| 120 it != file_system_map_.end(); |
| 121 ++it) { |
| 122 result.push_back(it->second->GetProvidedFileSystem()->GetFileSystemInfo()); |
| 123 } |
| 124 return result; |
| 125 } |
| 126 |
| 127 base::File::Error PluginService::MountFileSystem( |
| 128 const std::string &source_id, const MountOptions &options) { |
| 129 return MountFileSystemInternal( source_id, options, MOUNT_CONTEXT_USER ); |
| 130 } |
| 131 |
| 132 base::File::Error PluginService::MountFileSystemInternal( |
| 133 const std::string& source_id, |
| 134 const MountOptions& options, MountContext context) { |
| 135 DCHECK(thread_checker_.CalledOnValidThread()); |
| 136 // If already exists a file system provided by the same source with this |
| 137 // id, then abort. |
| 138 if (GetProvidedFileSystem(source_id, options.file_system_id)) { |
| 139 FOR_EACH_OBSERVER( |
| 140 Observer, observers_, |
| 141 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), context, |
| 142 base::File::FILE_ERROR_EXISTS)); |
| 143 return base::File::FILE_ERROR_EXISTS; |
| 144 } |
| 145 |
| 146 // Restrict number of file systems to prevent system abusing. |
| 147 if (file_system_map_.size() + 1 > kMaxFileSystems) { |
| 148 FOR_EACH_OBSERVER( |
| 149 Observer, observers_, |
| 150 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), context, |
| 151 base::File::FILE_ERROR_TOO_MANY_OPENED)); |
| 152 return base::File::FILE_ERROR_TOO_MANY_OPENED; |
| 153 } |
| 154 storage::ExternalMountPoints* const mount_points = |
| 155 storage::ExternalMountPoints::GetSystemInstance(); |
| 156 DCHECK(mount_points); |
| 157 |
| 158 const base::FilePath& mount_path = util::GetPluginMountPath( |
| 159 profile_, source_id, options.file_system_id); |
| 160 const std::string mount_point_name = mount_path.BaseName().AsUTF8Unsafe(); |
| 161 |
| 162 if (!mount_points->RegisterFileSystem( |
| 163 mount_point_name, storage::kFileSystemTypePluginProvided, |
| 164 storage::FileSystemMountOption( |
| 165 storage::FlushPolicy::FLUSH_ON_COMPLETION), |
| 166 mount_path)) { |
| 167 FOR_EACH_OBSERVER( |
| 168 Observer, observers_, |
| 169 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), context, |
| 170 base::File::FILE_ERROR_INVALID_OPERATION)); |
| 171 return base::File::FILE_ERROR_INVALID_OPERATION; |
| 172 } |
| 173 |
| 174 ProvidedFileSystemAdapter* file_system = NULL; |
| 175 ProvidedFileSystemInfo file_system_info = ProvidedFileSystemInfo( |
| 176 source_id, |
| 177 options, |
| 178 mount_path, |
| 179 false, |
| 180 extensions::SOURCE_NETWORK, |
| 181 Source_Type::plugin); |
| 182 file_system = CreateProvidedFileSystem(profile_, file_system_info); |
| 183 |
| 184 DCHECK(file_system); |
| 185 file_system_map_[FileSystemKey(source_id, options.file_system_id)] = |
| 186 file_system; |
| 187 mount_point_name_to_key_map_[mount_point_name] = |
| 188 FileSystemKey(source_id, options.file_system_id); |
| 189 |
| 190 |
| 191 FOR_EACH_OBSERVER(Observer, observers_, |
| 192 OnProvidedFileSystemMount(file_system_info, context, |
| 193 base::File::FILE_OK)); |
| 194 |
| 195 return base::File::FILE_OK; |
| 196 } |
| 197 |
| 198 base::File::Error PluginService::UnmountFileSystem( |
| 199 const std::string &source_id, |
| 200 const std::string &file_system_id, |
| 201 UnmountReason /*reason*/) { |
| 202 DCHECK(thread_checker_.CalledOnValidThread()); |
| 203 |
| 204 const ProvidedFileSystemMap::iterator file_system_it = |
| 205 file_system_map_.find(FileSystemKey(source_id, file_system_id)); |
| 206 if (file_system_it == file_system_map_.end()) { |
| 207 const ProvidedFileSystemInfo empty_file_system_info; |
| 208 FOR_EACH_OBSERVER( |
| 209 Observer, |
| 210 observers_, |
| 211 OnProvidedFileSystemUnmount(empty_file_system_info, |
| 212 base::File::FILE_ERROR_NOT_FOUND)); |
| 213 return base::File::FILE_ERROR_NOT_FOUND; |
| 214 } |
| 215 |
| 216 storage::ExternalMountPoints* const mount_points = |
| 217 storage::ExternalMountPoints::GetSystemInstance(); |
| 218 DCHECK(mount_points); |
| 219 |
| 220 const ProvidedFileSystemInfo& file_system_info = |
| 221 file_system_it->second->GetProvidedFileSystem()->GetFileSystemInfo(); |
| 222 |
| 223 const std::string mount_point_name = |
| 224 file_system_info.mount_path().BaseName().value(); |
| 225 if (!mount_points->RevokeFileSystem(mount_point_name)) { |
| 226 FOR_EACH_OBSERVER( |
| 227 Observer, |
| 228 observers_, |
| 229 OnProvidedFileSystemUnmount(file_system_info, |
| 230 base::File::FILE_ERROR_INVALID_OPERATION)); |
| 231 return base::File::FILE_ERROR_INVALID_OPERATION; |
| 232 } |
| 233 |
| 234 FOR_EACH_OBSERVER( |
| 235 Observer, |
| 236 observers_, |
| 237 OnProvidedFileSystemUnmount(file_system_info, base::File::FILE_OK)); |
| 238 |
| 239 mount_point_name_to_key_map_.erase(mount_point_name); |
| 240 |
| 241 delete file_system_it->second; |
| 242 file_system_map_.erase(file_system_it); |
| 243 |
| 244 return base::File::FILE_OK; |
| 245 } |
| 246 |
| 247 } // namespace file_system_provider |
| 248 } // namespace chromeos |
| 249 |
OLD | NEW |