| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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/fileapi/file_system_context.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/single_thread_task_runner.h" | |
| 9 #include "base/stl_util.h" | |
| 10 #include "googleurl/src/gurl.h" | |
| 11 #include "webkit/blob/file_stream_reader.h" | |
| 12 #include "webkit/fileapi/copy_or_move_file_validator.h" | |
| 13 #include "webkit/fileapi/external_mount_points.h" | |
| 14 #include "webkit/fileapi/file_stream_writer.h" | |
| 15 #include "webkit/fileapi/file_system_file_util.h" | |
| 16 #include "webkit/fileapi/file_system_operation.h" | |
| 17 #include "webkit/fileapi/file_system_options.h" | |
| 18 #include "webkit/fileapi/file_system_quota_client.h" | |
| 19 #include "webkit/fileapi/file_system_task_runners.h" | |
| 20 #include "webkit/fileapi/file_system_url.h" | |
| 21 #include "webkit/fileapi/file_system_util.h" | |
| 22 #include "webkit/fileapi/isolated_context.h" | |
| 23 #include "webkit/fileapi/isolated_mount_point_provider.h" | |
| 24 #include "webkit/fileapi/mount_points.h" | |
| 25 #include "webkit/fileapi/sandbox_mount_point_provider.h" | |
| 26 #include "webkit/fileapi/syncable/local_file_change_tracker.h" | |
| 27 #include "webkit/fileapi/syncable/local_file_sync_context.h" | |
| 28 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | |
| 29 #include "webkit/fileapi/test_mount_point_provider.h" | |
| 30 #include "webkit/quota/quota_manager.h" | |
| 31 #include "webkit/quota/special_storage_policy.h" | |
| 32 | |
| 33 #if defined(OS_CHROMEOS) | |
| 34 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" | |
| 35 #endif | |
| 36 | |
| 37 using quota::QuotaClient; | |
| 38 | |
| 39 namespace fileapi { | |
| 40 | |
| 41 namespace { | |
| 42 | |
| 43 QuotaClient* CreateQuotaClient( | |
| 44 FileSystemContext* context, | |
| 45 bool is_incognito) { | |
| 46 return new FileSystemQuotaClient(context, is_incognito); | |
| 47 } | |
| 48 | |
| 49 void DidOpenFileSystem( | |
| 50 const FileSystemContext::OpenFileSystemCallback& callback, | |
| 51 const GURL& filesystem_root, | |
| 52 const std::string& filesystem_name, | |
| 53 base::PlatformFileError error) { | |
| 54 callback.Run(error, filesystem_name, filesystem_root); | |
| 55 } | |
| 56 | |
| 57 } // namespace | |
| 58 | |
| 59 FileSystemContext::FileSystemContext( | |
| 60 scoped_ptr<FileSystemTaskRunners> task_runners, | |
| 61 ExternalMountPoints* external_mount_points, | |
| 62 quota::SpecialStoragePolicy* special_storage_policy, | |
| 63 quota::QuotaManagerProxy* quota_manager_proxy, | |
| 64 ScopedVector<FileSystemMountPointProvider> additional_providers, | |
| 65 const base::FilePath& partition_path, | |
| 66 const FileSystemOptions& options) | |
| 67 : task_runners_(task_runners.Pass()), | |
| 68 quota_manager_proxy_(quota_manager_proxy), | |
| 69 sandbox_provider_( | |
| 70 new SandboxMountPointProvider( | |
| 71 quota_manager_proxy, | |
| 72 task_runners_->file_task_runner(), | |
| 73 partition_path, | |
| 74 options, | |
| 75 special_storage_policy)), | |
| 76 isolated_provider_(new IsolatedMountPointProvider()), | |
| 77 additional_providers_(additional_providers.Pass()), | |
| 78 external_mount_points_(external_mount_points), | |
| 79 partition_path_(partition_path) { | |
| 80 DCHECK(task_runners_.get()); | |
| 81 | |
| 82 if (quota_manager_proxy) { | |
| 83 quota_manager_proxy->RegisterClient(CreateQuotaClient( | |
| 84 this, options.is_incognito())); | |
| 85 } | |
| 86 | |
| 87 RegisterMountPointProvider(sandbox_provider_.get()); | |
| 88 RegisterMountPointProvider(isolated_provider_.get()); | |
| 89 | |
| 90 #if defined(OS_CHROMEOS) | |
| 91 // TODO(kinuko): Move this out of webkit/fileapi layer. | |
| 92 DCHECK(external_mount_points); | |
| 93 external_provider_.reset( | |
| 94 new chromeos::CrosMountPointProvider( | |
| 95 special_storage_policy, | |
| 96 external_mount_points, | |
| 97 ExternalMountPoints::GetSystemInstance())); | |
| 98 RegisterMountPointProvider(external_provider_.get()); | |
| 99 #endif | |
| 100 | |
| 101 for (ScopedVector<FileSystemMountPointProvider>::const_iterator iter = | |
| 102 additional_providers_.begin(); | |
| 103 iter != additional_providers_.end(); ++iter) { | |
| 104 RegisterMountPointProvider(*iter); | |
| 105 } | |
| 106 | |
| 107 // Additional mount points must be added before regular system-wide | |
| 108 // mount points. | |
| 109 if (external_mount_points) | |
| 110 url_crackers_.push_back(external_mount_points); | |
| 111 url_crackers_.push_back(ExternalMountPoints::GetSystemInstance()); | |
| 112 url_crackers_.push_back(IsolatedContext::GetInstance()); | |
| 113 } | |
| 114 | |
| 115 bool FileSystemContext::DeleteDataForOriginOnFileThread( | |
| 116 const GURL& origin_url) { | |
| 117 DCHECK(task_runners_->file_task_runner()->RunsTasksOnCurrentThread()); | |
| 118 DCHECK(sandbox_provider()); | |
| 119 DCHECK(origin_url == origin_url.GetOrigin()); | |
| 120 | |
| 121 // Delete temporary and persistent data. | |
| 122 return | |
| 123 (sandbox_provider()->DeleteOriginDataOnFileThread( | |
| 124 this, quota_manager_proxy(), origin_url, | |
| 125 kFileSystemTypeTemporary) == | |
| 126 base::PLATFORM_FILE_OK) && | |
| 127 (sandbox_provider()->DeleteOriginDataOnFileThread( | |
| 128 this, quota_manager_proxy(), origin_url, | |
| 129 kFileSystemTypePersistent) == | |
| 130 base::PLATFORM_FILE_OK) && | |
| 131 (sandbox_provider()->DeleteOriginDataOnFileThread( | |
| 132 this, quota_manager_proxy(), origin_url, | |
| 133 kFileSystemTypeSyncable) == | |
| 134 base::PLATFORM_FILE_OK); | |
| 135 } | |
| 136 | |
| 137 FileSystemQuotaUtil* | |
| 138 FileSystemContext::GetQuotaUtil(FileSystemType type) const { | |
| 139 FileSystemMountPointProvider* mount_point_provider = | |
| 140 GetMountPointProvider(type); | |
| 141 if (!mount_point_provider) | |
| 142 return NULL; | |
| 143 return mount_point_provider->GetQuotaUtil(); | |
| 144 } | |
| 145 | |
| 146 AsyncFileUtil* FileSystemContext::GetAsyncFileUtil( | |
| 147 FileSystemType type) const { | |
| 148 FileSystemMountPointProvider* mount_point_provider = | |
| 149 GetMountPointProvider(type); | |
| 150 if (!mount_point_provider) | |
| 151 return NULL; | |
| 152 return mount_point_provider->GetAsyncFileUtil(type); | |
| 153 } | |
| 154 | |
| 155 CopyOrMoveFileValidatorFactory* | |
| 156 FileSystemContext::GetCopyOrMoveFileValidatorFactory( | |
| 157 FileSystemType type, base::PlatformFileError* error_code) const { | |
| 158 DCHECK(error_code); | |
| 159 *error_code = base::PLATFORM_FILE_OK; | |
| 160 FileSystemMountPointProvider* mount_point_provider = | |
| 161 GetMountPointProvider(type); | |
| 162 if (!mount_point_provider) | |
| 163 return NULL; | |
| 164 return mount_point_provider->GetCopyOrMoveFileValidatorFactory( | |
| 165 type, error_code); | |
| 166 } | |
| 167 | |
| 168 FileSystemMountPointProvider* FileSystemContext::GetMountPointProvider( | |
| 169 FileSystemType type) const { | |
| 170 MountPointProviderMap::const_iterator found = provider_map_.find(type); | |
| 171 if (found != provider_map_.end()) | |
| 172 return found->second; | |
| 173 NOTREACHED() << "Unknown filesystem type: " << type; | |
| 174 return NULL; | |
| 175 } | |
| 176 | |
| 177 const UpdateObserverList* FileSystemContext::GetUpdateObservers( | |
| 178 FileSystemType type) const { | |
| 179 // Currently update observer is only available in SandboxMountPointProvider | |
| 180 // and TestMountPointProvider. | |
| 181 // TODO(kinuko): Probably GetUpdateObservers() virtual method should be | |
| 182 // added to FileSystemMountPointProvider interface and be called like | |
| 183 // other GetFoo() methods do. | |
| 184 if (SandboxMountPointProvider::IsSandboxType(type)) | |
| 185 return sandbox_provider()->GetUpdateObservers(type); | |
| 186 if (type != kFileSystemTypeTest) | |
| 187 return NULL; | |
| 188 FileSystemMountPointProvider* mount_point_provider = | |
| 189 GetMountPointProvider(type); | |
| 190 return static_cast<TestMountPointProvider*>( | |
| 191 mount_point_provider)->GetUpdateObservers(type); | |
| 192 } | |
| 193 | |
| 194 SandboxMountPointProvider* | |
| 195 FileSystemContext::sandbox_provider() const { | |
| 196 return sandbox_provider_.get(); | |
| 197 } | |
| 198 | |
| 199 ExternalFileSystemMountPointProvider* | |
| 200 FileSystemContext::external_provider() const { | |
| 201 return external_provider_.get(); | |
| 202 } | |
| 203 | |
| 204 void FileSystemContext::OpenFileSystem( | |
| 205 const GURL& origin_url, | |
| 206 FileSystemType type, | |
| 207 bool create, | |
| 208 const OpenFileSystemCallback& callback) { | |
| 209 DCHECK(!callback.is_null()); | |
| 210 | |
| 211 FileSystemMountPointProvider* mount_point_provider = | |
| 212 GetMountPointProvider(type); | |
| 213 if (!mount_point_provider) { | |
| 214 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, std::string(), GURL()); | |
| 215 return; | |
| 216 } | |
| 217 | |
| 218 GURL root_url = GetFileSystemRootURI(origin_url, type); | |
| 219 std::string name = GetFileSystemName(origin_url, type); | |
| 220 | |
| 221 mount_point_provider->ValidateFileSystemRoot( | |
| 222 origin_url, type, create, | |
| 223 base::Bind(&DidOpenFileSystem, callback, root_url, name)); | |
| 224 } | |
| 225 | |
| 226 void FileSystemContext::OpenSyncableFileSystem( | |
| 227 const std::string& mount_name, | |
| 228 const GURL& origin_url, | |
| 229 FileSystemType type, | |
| 230 bool create, | |
| 231 const OpenFileSystemCallback& callback) { | |
| 232 DCHECK(!callback.is_null()); | |
| 233 | |
| 234 DCHECK(type == kFileSystemTypeSyncable); | |
| 235 | |
| 236 GURL root_url = sync_file_system::GetSyncableFileSystemRootURI( | |
| 237 origin_url, mount_name); | |
| 238 std::string name = GetFileSystemName(origin_url, kFileSystemTypeSyncable); | |
| 239 | |
| 240 FileSystemMountPointProvider* mount_point_provider = | |
| 241 GetMountPointProvider(type); | |
| 242 DCHECK(mount_point_provider); | |
| 243 mount_point_provider->ValidateFileSystemRoot( | |
| 244 origin_url, type, create, | |
| 245 base::Bind(&DidOpenFileSystem, callback, root_url, name)); | |
| 246 } | |
| 247 | |
| 248 void FileSystemContext::DeleteFileSystem( | |
| 249 const GURL& origin_url, | |
| 250 FileSystemType type, | |
| 251 const DeleteFileSystemCallback& callback) { | |
| 252 DCHECK(origin_url == origin_url.GetOrigin()); | |
| 253 FileSystemMountPointProvider* mount_point_provider = | |
| 254 GetMountPointProvider(type); | |
| 255 if (!mount_point_provider) { | |
| 256 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 257 return; | |
| 258 } | |
| 259 | |
| 260 mount_point_provider->DeleteFileSystem(origin_url, type, this, callback); | |
| 261 } | |
| 262 | |
| 263 FileSystemOperation* FileSystemContext::CreateFileSystemOperation( | |
| 264 const FileSystemURL& url, base::PlatformFileError* error_code) { | |
| 265 if (!url.is_valid()) { | |
| 266 if (error_code) | |
| 267 *error_code = base::PLATFORM_FILE_ERROR_INVALID_URL; | |
| 268 return NULL; | |
| 269 } | |
| 270 | |
| 271 FileSystemMountPointProvider* mount_point_provider = | |
| 272 GetMountPointProvider(url.type()); | |
| 273 if (!mount_point_provider) { | |
| 274 if (error_code) | |
| 275 *error_code = base::PLATFORM_FILE_ERROR_FAILED; | |
| 276 return NULL; | |
| 277 } | |
| 278 | |
| 279 base::PlatformFileError fs_error = base::PLATFORM_FILE_OK; | |
| 280 FileSystemOperation* operation = | |
| 281 mount_point_provider->CreateFileSystemOperation(url, this, &fs_error); | |
| 282 | |
| 283 if (error_code) | |
| 284 *error_code = fs_error; | |
| 285 return operation; | |
| 286 } | |
| 287 | |
| 288 scoped_ptr<webkit_blob::FileStreamReader> | |
| 289 FileSystemContext::CreateFileStreamReader( | |
| 290 const FileSystemURL& url, | |
| 291 int64 offset, | |
| 292 const base::Time& expected_modification_time) { | |
| 293 if (!url.is_valid()) | |
| 294 return scoped_ptr<webkit_blob::FileStreamReader>(); | |
| 295 FileSystemMountPointProvider* mount_point_provider = | |
| 296 GetMountPointProvider(url.type()); | |
| 297 if (!mount_point_provider) | |
| 298 return scoped_ptr<webkit_blob::FileStreamReader>(); | |
| 299 return mount_point_provider->CreateFileStreamReader( | |
| 300 url, offset, expected_modification_time, this); | |
| 301 } | |
| 302 | |
| 303 scoped_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter( | |
| 304 const FileSystemURL& url, | |
| 305 int64 offset) { | |
| 306 if (!url.is_valid()) | |
| 307 return scoped_ptr<FileStreamWriter>(); | |
| 308 FileSystemMountPointProvider* mount_point_provider = | |
| 309 GetMountPointProvider(url.type()); | |
| 310 if (!mount_point_provider) | |
| 311 return scoped_ptr<FileStreamWriter>(); | |
| 312 return mount_point_provider->CreateFileStreamWriter(url, offset, this); | |
| 313 } | |
| 314 | |
| 315 void FileSystemContext::SetLocalFileChangeTracker( | |
| 316 scoped_ptr<sync_file_system::LocalFileChangeTracker> tracker) { | |
| 317 DCHECK(!change_tracker_.get()); | |
| 318 DCHECK(tracker.get()); | |
| 319 change_tracker_ = tracker.Pass(); | |
| 320 sandbox_provider_->AddSyncableFileUpdateObserver( | |
| 321 change_tracker_.get(), | |
| 322 task_runners_->file_task_runner()); | |
| 323 sandbox_provider_->AddSyncableFileChangeObserver( | |
| 324 change_tracker_.get(), | |
| 325 task_runners_->file_task_runner()); | |
| 326 } | |
| 327 | |
| 328 void FileSystemContext::set_sync_context( | |
| 329 sync_file_system::LocalFileSyncContext* sync_context) { | |
| 330 sync_context_ = sync_context; | |
| 331 } | |
| 332 | |
| 333 FileSystemURL FileSystemContext::CrackURL(const GURL& url) const { | |
| 334 return CrackFileSystemURL(FileSystemURL(url)); | |
| 335 } | |
| 336 | |
| 337 FileSystemURL FileSystemContext::CreateCrackedFileSystemURL( | |
| 338 const GURL& origin, | |
| 339 FileSystemType type, | |
| 340 const base::FilePath& path) const { | |
| 341 return CrackFileSystemURL(FileSystemURL(origin, type, path)); | |
| 342 } | |
| 343 | |
| 344 FileSystemContext::~FileSystemContext() { | |
| 345 task_runners_->file_task_runner()->DeleteSoon( | |
| 346 FROM_HERE, change_tracker_.release()); | |
| 347 } | |
| 348 | |
| 349 void FileSystemContext::DeleteOnCorrectThread() const { | |
| 350 if (!task_runners_->io_task_runner()->RunsTasksOnCurrentThread() && | |
| 351 task_runners_->io_task_runner()->DeleteSoon(FROM_HERE, this)) { | |
| 352 return; | |
| 353 } | |
| 354 delete this; | |
| 355 } | |
| 356 | |
| 357 FileSystemURL FileSystemContext::CrackFileSystemURL( | |
| 358 const FileSystemURL& url) const { | |
| 359 if (!url.is_valid()) | |
| 360 return FileSystemURL(); | |
| 361 | |
| 362 // The returned value in case there is no crackers which can crack the url. | |
| 363 // This is valid situation for non isolated/external file systems. | |
| 364 FileSystemURL current = url; | |
| 365 | |
| 366 // File system may be mounted multiple times (e.g., an isolated filesystem on | |
| 367 // top of an external filesystem). Hence cracking needs to be iterated. | |
| 368 for (;;) { | |
| 369 FileSystemURL cracked = current; | |
| 370 for (size_t i = 0; i < url_crackers_.size(); ++i) { | |
| 371 if (!url_crackers_[i]->HandlesFileSystemMountType(current.type())) | |
| 372 continue; | |
| 373 cracked = url_crackers_[i]->CrackFileSystemURL(current); | |
| 374 if (cracked.is_valid()) | |
| 375 break; | |
| 376 } | |
| 377 if (cracked == current) | |
| 378 break; | |
| 379 current = cracked; | |
| 380 } | |
| 381 return current; | |
| 382 } | |
| 383 | |
| 384 FileSystemFileUtil* FileSystemContext::GetFileUtil( | |
| 385 FileSystemType type) const { | |
| 386 FileSystemMountPointProvider* mount_point_provider = | |
| 387 GetMountPointProvider(type); | |
| 388 if (!mount_point_provider) | |
| 389 return NULL; | |
| 390 return mount_point_provider->GetFileUtil(type); | |
| 391 } | |
| 392 | |
| 393 void FileSystemContext::RegisterMountPointProvider( | |
| 394 FileSystemMountPointProvider* provider) { | |
| 395 const FileSystemType mount_types[] = { | |
| 396 kFileSystemTypeTemporary, | |
| 397 kFileSystemTypePersistent, | |
| 398 kFileSystemTypeIsolated, | |
| 399 kFileSystemTypeExternal, | |
| 400 }; | |
| 401 // Register mount point providers for public mount types. | |
| 402 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(mount_types); ++j) { | |
| 403 if (provider->CanHandleType(mount_types[j])) { | |
| 404 const bool inserted = provider_map_.insert( | |
| 405 std::make_pair(mount_types[j], provider)).second; | |
| 406 DCHECK(inserted); | |
| 407 } | |
| 408 } | |
| 409 // Register mount point providers for internal types. | |
| 410 for (int t = kFileSystemInternalTypeEnumStart + 1; | |
| 411 t < kFileSystemInternalTypeEnumEnd; ++t) { | |
| 412 FileSystemType type = static_cast<FileSystemType>(t); | |
| 413 if (provider->CanHandleType(type)) { | |
| 414 const bool inserted = provider_map_.insert( | |
| 415 std::make_pair(type, provider)).second; | |
| 416 DCHECK(inserted); | |
| 417 } | |
| 418 } | |
| 419 } | |
| 420 | |
| 421 } // namespace fileapi | |
| OLD | NEW |