| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 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 "webkit/browser/fileapi/plugin_private_file_system_backend.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/stl_util.h" | |
| 10 #include "base/synchronization/lock.h" | |
| 11 #include "base/task_runner_util.h" | |
| 12 #include "net/base/net_util.h" | |
| 13 #include "webkit/browser/blob/file_stream_reader.h" | |
| 14 #include "webkit/browser/fileapi/async_file_util_adapter.h" | |
| 15 #include "webkit/browser/fileapi/file_stream_writer.h" | |
| 16 #include "webkit/browser/fileapi/file_system_context.h" | |
| 17 #include "webkit/browser/fileapi/file_system_operation.h" | |
| 18 #include "webkit/browser/fileapi/file_system_operation_context.h" | |
| 19 #include "webkit/browser/fileapi/file_system_options.h" | |
| 20 #include "webkit/browser/fileapi/isolated_context.h" | |
| 21 #include "webkit/browser/fileapi/obfuscated_file_util.h" | |
| 22 #include "webkit/browser/fileapi/quota/quota_reservation.h" | |
| 23 #include "webkit/common/fileapi/file_system_util.h" | |
| 24 | |
| 25 namespace storage { | |
| 26 | |
| 27 class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap { | |
| 28 public: | |
| 29 explicit FileSystemIDToPluginMap(base::SequencedTaskRunner* task_runner) | |
| 30 : task_runner_(task_runner) {} | |
| 31 ~FileSystemIDToPluginMap() {} | |
| 32 | |
| 33 std::string GetPluginIDForURL(const FileSystemURL& url) { | |
| 34 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 35 Map::iterator found = map_.find(url.filesystem_id()); | |
| 36 if (url.type() != kFileSystemTypePluginPrivate || found == map_.end()) { | |
| 37 NOTREACHED() << "Unsupported url is given: " << url.DebugString(); | |
| 38 return std::string(); | |
| 39 } | |
| 40 return found->second; | |
| 41 } | |
| 42 | |
| 43 void RegisterFileSystem(const std::string& filesystem_id, | |
| 44 const std::string& plugin_id) { | |
| 45 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 46 DCHECK(!filesystem_id.empty()); | |
| 47 DCHECK(!ContainsKey(map_, filesystem_id)) << filesystem_id; | |
| 48 map_[filesystem_id] = plugin_id; | |
| 49 } | |
| 50 | |
| 51 void RemoveFileSystem(const std::string& filesystem_id) { | |
| 52 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 53 map_.erase(filesystem_id); | |
| 54 } | |
| 55 | |
| 56 private: | |
| 57 typedef std::map<std::string, std::string> Map; | |
| 58 scoped_refptr<base::SequencedTaskRunner> task_runner_; | |
| 59 Map map_; | |
| 60 }; | |
| 61 | |
| 62 namespace { | |
| 63 | |
| 64 const base::FilePath::CharType* kFileSystemDirectory = | |
| 65 SandboxFileSystemBackendDelegate::kFileSystemDirectory; | |
| 66 const base::FilePath::CharType* kPluginPrivateDirectory = | |
| 67 FILE_PATH_LITERAL("Plugins"); | |
| 68 | |
| 69 base::File::Error OpenFileSystemOnFileTaskRunner( | |
| 70 ObfuscatedFileUtil* file_util, | |
| 71 PluginPrivateFileSystemBackend::FileSystemIDToPluginMap* plugin_map, | |
| 72 const GURL& origin_url, | |
| 73 const std::string& filesystem_id, | |
| 74 const std::string& plugin_id, | |
| 75 OpenFileSystemMode mode) { | |
| 76 base::File::Error error = base::File::FILE_ERROR_FAILED; | |
| 77 const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT); | |
| 78 file_util->GetDirectoryForOriginAndType( | |
| 79 origin_url, plugin_id, create, &error); | |
| 80 if (error == base::File::FILE_OK) | |
| 81 plugin_map->RegisterFileSystem(filesystem_id, plugin_id); | |
| 82 return error; | |
| 83 } | |
| 84 | |
| 85 } // namespace | |
| 86 | |
| 87 PluginPrivateFileSystemBackend::PluginPrivateFileSystemBackend( | |
| 88 base::SequencedTaskRunner* file_task_runner, | |
| 89 const base::FilePath& profile_path, | |
| 90 storage::SpecialStoragePolicy* special_storage_policy, | |
| 91 const FileSystemOptions& file_system_options) | |
| 92 : file_task_runner_(file_task_runner), | |
| 93 file_system_options_(file_system_options), | |
| 94 base_path_(profile_path.Append(kFileSystemDirectory) | |
| 95 .Append(kPluginPrivateDirectory)), | |
| 96 plugin_map_(new FileSystemIDToPluginMap(file_task_runner)), | |
| 97 weak_factory_(this) { | |
| 98 file_util_.reset( | |
| 99 new AsyncFileUtilAdapter(new ObfuscatedFileUtil( | |
| 100 special_storage_policy, | |
| 101 base_path_, file_system_options.env_override(), | |
| 102 file_task_runner, | |
| 103 base::Bind(&FileSystemIDToPluginMap::GetPluginIDForURL, | |
| 104 base::Owned(plugin_map_)), | |
| 105 std::set<std::string>(), | |
| 106 NULL))); | |
| 107 } | |
| 108 | |
| 109 PluginPrivateFileSystemBackend::~PluginPrivateFileSystemBackend() { | |
| 110 if (!file_task_runner_->RunsTasksOnCurrentThread()) { | |
| 111 AsyncFileUtil* file_util = file_util_.release(); | |
| 112 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_util)) | |
| 113 delete file_util; | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 void PluginPrivateFileSystemBackend::OpenPrivateFileSystem( | |
| 118 const GURL& origin_url, | |
| 119 FileSystemType type, | |
| 120 const std::string& filesystem_id, | |
| 121 const std::string& plugin_id, | |
| 122 OpenFileSystemMode mode, | |
| 123 const StatusCallback& callback) { | |
| 124 if (!CanHandleType(type) || file_system_options_.is_incognito()) { | |
| 125 base::MessageLoopProxy::current()->PostTask( | |
| 126 FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_SECURITY)); | |
| 127 return; | |
| 128 } | |
| 129 | |
| 130 PostTaskAndReplyWithResult( | |
| 131 file_task_runner_.get(), | |
| 132 FROM_HERE, | |
| 133 base::Bind(&OpenFileSystemOnFileTaskRunner, | |
| 134 obfuscated_file_util(), plugin_map_, | |
| 135 origin_url, filesystem_id, plugin_id, mode), | |
| 136 callback); | |
| 137 } | |
| 138 | |
| 139 bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const { | |
| 140 return type == kFileSystemTypePluginPrivate; | |
| 141 } | |
| 142 | |
| 143 void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) { | |
| 144 } | |
| 145 | |
| 146 void PluginPrivateFileSystemBackend::ResolveURL( | |
| 147 const FileSystemURL& url, | |
| 148 OpenFileSystemMode mode, | |
| 149 const OpenFileSystemCallback& callback) { | |
| 150 // We never allow opening a new plugin-private filesystem via usual | |
| 151 // ResolveURL. | |
| 152 base::MessageLoopProxy::current()->PostTask( | |
| 153 FROM_HERE, | |
| 154 base::Bind(callback, GURL(), std::string(), | |
| 155 base::File::FILE_ERROR_SECURITY)); | |
| 156 } | |
| 157 | |
| 158 AsyncFileUtil* | |
| 159 PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) { | |
| 160 return file_util_.get(); | |
| 161 } | |
| 162 | |
| 163 WatcherManager* PluginPrivateFileSystemBackend::GetWatcherManager( | |
| 164 FileSystemType type) { | |
| 165 return NULL; | |
| 166 } | |
| 167 | |
| 168 CopyOrMoveFileValidatorFactory* | |
| 169 PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory( | |
| 170 FileSystemType type, | |
| 171 base::File::Error* error_code) { | |
| 172 DCHECK(error_code); | |
| 173 *error_code = base::File::FILE_OK; | |
| 174 return NULL; | |
| 175 } | |
| 176 | |
| 177 FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation( | |
| 178 const FileSystemURL& url, | |
| 179 FileSystemContext* context, | |
| 180 base::File::Error* error_code) const { | |
| 181 scoped_ptr<FileSystemOperationContext> operation_context( | |
| 182 new FileSystemOperationContext(context)); | |
| 183 return FileSystemOperation::Create(url, context, operation_context.Pass()); | |
| 184 } | |
| 185 | |
| 186 bool PluginPrivateFileSystemBackend::SupportsStreaming( | |
| 187 const storage::FileSystemURL& url) const { | |
| 188 return false; | |
| 189 } | |
| 190 | |
| 191 bool PluginPrivateFileSystemBackend::HasInplaceCopyImplementation( | |
| 192 storage::FileSystemType type) const { | |
| 193 return false; | |
| 194 } | |
| 195 | |
| 196 scoped_ptr<storage::FileStreamReader> | |
| 197 PluginPrivateFileSystemBackend::CreateFileStreamReader( | |
| 198 const FileSystemURL& url, | |
| 199 int64 offset, | |
| 200 const base::Time& expected_modification_time, | |
| 201 FileSystemContext* context) const { | |
| 202 return scoped_ptr<storage::FileStreamReader>(); | |
| 203 } | |
| 204 | |
| 205 scoped_ptr<FileStreamWriter> | |
| 206 PluginPrivateFileSystemBackend::CreateFileStreamWriter( | |
| 207 const FileSystemURL& url, | |
| 208 int64 offset, | |
| 209 FileSystemContext* context) const { | |
| 210 return scoped_ptr<FileStreamWriter>(); | |
| 211 } | |
| 212 | |
| 213 FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() { | |
| 214 return this; | |
| 215 } | |
| 216 | |
| 217 base::File::Error | |
| 218 PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner( | |
| 219 FileSystemContext* context, | |
| 220 storage::QuotaManagerProxy* proxy, | |
| 221 const GURL& origin_url, | |
| 222 FileSystemType type) { | |
| 223 if (!CanHandleType(type)) | |
| 224 return base::File::FILE_ERROR_SECURITY; | |
| 225 bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType( | |
| 226 origin_url, std::string()); | |
| 227 if (result) | |
| 228 return base::File::FILE_OK; | |
| 229 return base::File::FILE_ERROR_FAILED; | |
| 230 } | |
| 231 | |
| 232 void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner( | |
| 233 FileSystemType type, | |
| 234 std::set<GURL>* origins) { | |
| 235 if (!CanHandleType(type)) | |
| 236 return; | |
| 237 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( | |
| 238 obfuscated_file_util()->CreateOriginEnumerator()); | |
| 239 GURL origin; | |
| 240 while (!(origin = enumerator->Next()).is_empty()) | |
| 241 origins->insert(origin); | |
| 242 } | |
| 243 | |
| 244 void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner( | |
| 245 FileSystemType type, | |
| 246 const std::string& host, | |
| 247 std::set<GURL>* origins) { | |
| 248 if (!CanHandleType(type)) | |
| 249 return; | |
| 250 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( | |
| 251 obfuscated_file_util()->CreateOriginEnumerator()); | |
| 252 GURL origin; | |
| 253 while (!(origin = enumerator->Next()).is_empty()) { | |
| 254 if (host == net::GetHostOrSpecFromURL(origin)) | |
| 255 origins->insert(origin); | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner( | |
| 260 FileSystemContext* context, | |
| 261 const GURL& origin_url, | |
| 262 FileSystemType type) { | |
| 263 // We don't track usage on this filesystem. | |
| 264 return 0; | |
| 265 } | |
| 266 | |
| 267 scoped_refptr<QuotaReservation> | |
| 268 PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner( | |
| 269 const GURL& origin_url, | |
| 270 FileSystemType type) { | |
| 271 // We don't track usage on this filesystem. | |
| 272 NOTREACHED(); | |
| 273 return scoped_refptr<QuotaReservation>(); | |
| 274 } | |
| 275 | |
| 276 void PluginPrivateFileSystemBackend::AddFileUpdateObserver( | |
| 277 FileSystemType type, | |
| 278 FileUpdateObserver* observer, | |
| 279 base::SequencedTaskRunner* task_runner) {} | |
| 280 | |
| 281 void PluginPrivateFileSystemBackend::AddFileChangeObserver( | |
| 282 FileSystemType type, | |
| 283 FileChangeObserver* observer, | |
| 284 base::SequencedTaskRunner* task_runner) {} | |
| 285 | |
| 286 void PluginPrivateFileSystemBackend::AddFileAccessObserver( | |
| 287 FileSystemType type, | |
| 288 FileAccessObserver* observer, | |
| 289 base::SequencedTaskRunner* task_runner) {} | |
| 290 | |
| 291 const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers( | |
| 292 FileSystemType type) const { | |
| 293 return NULL; | |
| 294 } | |
| 295 | |
| 296 const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers( | |
| 297 FileSystemType type) const { | |
| 298 return NULL; | |
| 299 } | |
| 300 | |
| 301 const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers( | |
| 302 FileSystemType type) const { | |
| 303 return NULL; | |
| 304 } | |
| 305 | |
| 306 ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() { | |
| 307 return static_cast<ObfuscatedFileUtil*>( | |
| 308 static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util()); | |
| 309 } | |
| 310 | |
| 311 } // namespace storage | |
| OLD | NEW |