OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/fileapi/sandbox_mount_point_provider.h" | 5 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_callback_factory.h" | 9 #include "base/memory/scoped_callback_factory.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
15 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
16 #include "googleurl/src/gurl.h" | 16 #include "googleurl/src/gurl.h" |
17 #include "net/base/net_util.h" | 17 #include "net/base/net_util.h" |
18 #include "webkit/fileapi/file_system_operation_context.h" | 18 #include "webkit/fileapi/file_system_operation_context.h" |
19 #include "webkit/fileapi/file_system_path_manager.h" | 19 #include "webkit/fileapi/file_system_path_manager.h" |
20 #include "webkit/fileapi/file_system_types.h" | 20 #include "webkit/fileapi/file_system_types.h" |
21 #include "webkit/fileapi/file_system_usage_cache.h" | 21 #include "webkit/fileapi/file_system_usage_cache.h" |
22 #include "webkit/fileapi/file_system_util.h" | 22 #include "webkit/fileapi/file_system_util.h" |
23 #include "webkit/fileapi/local_file_system_file_util.h" | 23 #include "webkit/fileapi/obfuscated_file_util.h" |
24 #include "webkit/fileapi/obfuscated_file_system_file_util.h" | |
25 #include "webkit/fileapi/quota_file_util.h" | 24 #include "webkit/fileapi/quota_file_util.h" |
26 #include "webkit/glue/webkit_glue.h" | 25 #include "webkit/glue/webkit_glue.h" |
27 #include "webkit/quota/quota_manager.h" | 26 #include "webkit/quota/quota_manager.h" |
28 | 27 |
29 using quota::QuotaManagerProxy; | 28 using quota::QuotaManagerProxy; |
30 | 29 |
31 namespace { | 30 namespace { |
32 | 31 |
33 static const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = | 32 static const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = |
34 FILE_PATH_LITERAL("chrome-"); | 33 FILE_PATH_LITERAL("chrome-"); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 88 } |
90 if (unique->empty()) | 89 if (unique->empty()) |
91 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 90 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
92 return base::PLATFORM_FILE_OK; | 91 return base::PLATFORM_FILE_OK; |
93 } | 92 } |
94 | 93 |
95 class ObfuscatedOriginEnumerator | 94 class ObfuscatedOriginEnumerator |
96 : public fileapi::SandboxMountPointProvider::OriginEnumerator { | 95 : public fileapi::SandboxMountPointProvider::OriginEnumerator { |
97 public: | 96 public: |
98 explicit ObfuscatedOriginEnumerator( | 97 explicit ObfuscatedOriginEnumerator( |
99 fileapi::ObfuscatedFileSystemFileUtil* file_util) { | 98 fileapi::ObfuscatedFileUtil* file_util) { |
100 enum_.reset(file_util->CreateOriginEnumerator()); | 99 enum_.reset(file_util->CreateOriginEnumerator()); |
101 } | 100 } |
102 virtual ~ObfuscatedOriginEnumerator() {} | 101 virtual ~ObfuscatedOriginEnumerator() {} |
103 | 102 |
104 virtual GURL Next() OVERRIDE { | 103 virtual GURL Next() OVERRIDE { |
105 return enum_->Next(); | 104 return enum_->Next(); |
106 } | 105 } |
107 | 106 |
108 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { | 107 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { |
109 return enum_->HasFileSystemType(type); | 108 return enum_->HasFileSystemType(type); |
110 } | 109 } |
111 | 110 |
112 private: | 111 private: |
113 scoped_ptr<fileapi::ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator> | 112 scoped_ptr<fileapi::ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; |
114 enum_; | |
115 }; | 113 }; |
116 | 114 |
117 class OldSandboxOriginEnumerator | 115 class OldSandboxOriginEnumerator |
118 : public fileapi::SandboxMountPointProvider::OriginEnumerator { | 116 : public fileapi::SandboxMountPointProvider::OriginEnumerator { |
119 public: | 117 public: |
120 explicit OldSandboxOriginEnumerator(const FilePath& base_path) | 118 explicit OldSandboxOriginEnumerator(const FilePath& base_path) |
121 : enumerator_(base_path, false /* recursive */, | 119 : enumerator_(base_path, false /* recursive */, |
122 file_util::FileEnumerator::DIRECTORIES) {} | 120 file_util::FileEnumerator::DIRECTORIES) {} |
123 virtual ~OldSandboxOriginEnumerator() {} | 121 virtual ~OldSandboxOriginEnumerator() {} |
124 | 122 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 FilePath base_path = OldGetBaseDirectoryForOrigin( | 163 FilePath base_path = OldGetBaseDirectoryForOrigin( |
166 old_base_path, origin_url); | 164 old_base_path, origin_url); |
167 if (base_path.empty()) { | 165 if (base_path.empty()) { |
168 NOTREACHED(); | 166 NOTREACHED(); |
169 return FilePath(); | 167 return FilePath(); |
170 } | 168 } |
171 return base_path.AppendASCII(type_string); | 169 return base_path.AppendASCII(type_string); |
172 } | 170 } |
173 | 171 |
174 bool MigrateOneOldFileSystem( | 172 bool MigrateOneOldFileSystem( |
175 fileapi::ObfuscatedFileSystemFileUtil* file_util, | 173 fileapi::ObfuscatedFileUtil* file_util, |
176 const FilePath& old_base_path, const GURL& origin, | 174 const FilePath& old_base_path, const GURL& origin, |
177 fileapi::FileSystemType type) { | 175 fileapi::FileSystemType type) { |
178 FilePath base_path = OldGetBaseDirectoryForOriginAndType( | 176 FilePath base_path = OldGetBaseDirectoryForOriginAndType( |
179 old_base_path, origin, type); | 177 old_base_path, origin, type); |
180 if (base_path.empty()) | 178 if (base_path.empty()) |
181 return false; | 179 return false; |
182 | 180 |
183 FilePath root; | 181 FilePath root; |
184 base::PlatformFileError result = OldReadOriginDirectory(base_path, &root); | 182 base::PlatformFileError result = OldReadOriginDirectory(base_path, &root); |
185 if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result) | 183 if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result) |
186 return true; // There was nothing to migrate; call that a success. | 184 return true; // There was nothing to migrate; call that a success. |
187 | 185 |
188 // If we found more than one filesystem [a problem we don't know how to | 186 // If we found more than one filesystem [a problem we don't know how to |
189 // solve], the data is already not accessible through Chrome, so it won't do | 187 // solve], the data is already not accessible through Chrome, so it won't do |
190 // any harm not to migrate it. Just flag it as an error, so that we don't | 188 // any harm not to migrate it. Just flag it as an error, so that we don't |
191 // delete it. | 189 // delete it. |
192 if (base::PLATFORM_FILE_OK != result) | 190 if (base::PLATFORM_FILE_OK != result) |
193 return false; | 191 return false; |
194 | 192 |
195 if (!file_util->MigrateFromOldSandbox(origin, type, root)) { | 193 if (!file_util->MigrateFromOldSandbox(origin, type, root)) { |
196 LOG(WARNING) << "Failed to migrate filesystem for origin " << origin << | 194 LOG(WARNING) << "Failed to migrate filesystem for origin " << origin << |
197 " and type " << type; | 195 " and type " << type; |
198 return false; | 196 return false; |
199 } | 197 } |
200 return true; | 198 return true; |
201 } | 199 } |
202 | 200 |
203 void MigrateAllOldFileSystems( | 201 void MigrateAllOldFileSystems( |
204 fileapi::ObfuscatedFileSystemFileUtil* file_util, | 202 fileapi::ObfuscatedFileUtil* file_util, |
205 const FilePath& old_base_path) { | 203 const FilePath& old_base_path) { |
206 scoped_ptr<OldSandboxOriginEnumerator> old_origins( | 204 scoped_ptr<OldSandboxOriginEnumerator> old_origins( |
207 new OldSandboxOriginEnumerator(old_base_path)); | 205 new OldSandboxOriginEnumerator(old_base_path)); |
208 GURL origin; | 206 GURL origin; |
209 int failures = 0; | 207 int failures = 0; |
210 while (!(origin = old_origins->Next()).is_empty()) { | 208 while (!(origin = old_origins->Next()).is_empty()) { |
211 int failures_this_origin = 0; | 209 int failures_this_origin = 0; |
212 if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) && | 210 if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) && |
213 !MigrateOneOldFileSystem( | 211 !MigrateOneOldFileSystem( |
214 file_util, old_base_path, origin, | 212 file_util, old_base_path, origin, |
(...skipping 28 matching lines...) Expand all Loading... |
243 } | 241 } |
244 } | 242 } |
245 | 243 |
246 // A migration, whether successful or not, will try to move this directory out | 244 // A migration, whether successful or not, will try to move this directory out |
247 // of the way so that we never try to migrate it again. We need to do this | 245 // of the way so that we never try to migrate it again. We need to do this |
248 // check on all public entry points in this file, so that it's guaranteed to be | 246 // check on all public entry points in this file, so that it's guaranteed to be |
249 // done before anyone looks up a filesystem. Most entry points start by trying | 247 // done before anyone looks up a filesystem. Most entry points start by trying |
250 // to look up the filesystem's root, so we can take care of most of them by | 248 // to look up the filesystem's root, so we can take care of most of them by |
251 // putting a check there. | 249 // putting a check there. |
252 void MigrateIfNeeded( | 250 void MigrateIfNeeded( |
253 fileapi::ObfuscatedFileSystemFileUtil* file_util, | 251 fileapi::ObfuscatedFileUtil* file_util, |
254 const FilePath& old_base_path) { | 252 const FilePath& old_base_path) { |
255 if (file_util::DirectoryExists(old_base_path)) | 253 if (file_util::DirectoryExists(old_base_path)) |
256 MigrateAllOldFileSystems(file_util, old_base_path); | 254 MigrateAllOldFileSystems(file_util, old_base_path); |
257 } | 255 } |
258 | 256 |
259 } // anonymous namespace | 257 } // anonymous namespace |
260 | 258 |
261 namespace fileapi { | 259 namespace fileapi { |
262 | 260 |
263 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] = | 261 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] = |
264 FILE_PATH_LITERAL("FileSystem"); | 262 FILE_PATH_LITERAL("FileSystem"); |
265 | 263 |
266 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] = | 264 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] = |
267 FILE_PATH_LITERAL("File System"); | 265 FILE_PATH_LITERAL("File System"); |
268 | 266 |
269 const FilePath::CharType | 267 const FilePath::CharType |
270 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] = | 268 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] = |
271 FILE_PATH_LITERAL("FS.old"); | 269 FILE_PATH_LITERAL("FS.old"); |
272 | 270 |
273 SandboxMountPointProvider::SandboxMountPointProvider( | 271 SandboxMountPointProvider::SandboxMountPointProvider( |
274 FileSystemPathManager* path_manager, | 272 FileSystemPathManager* path_manager, |
275 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 273 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
276 const FilePath& profile_path) | 274 const FilePath& profile_path) |
277 : FileSystemQuotaUtil(file_message_loop), | 275 : FileSystemQuotaUtil(file_message_loop), |
278 path_manager_(path_manager), | 276 path_manager_(path_manager), |
279 file_message_loop_(file_message_loop), | 277 file_message_loop_(file_message_loop), |
280 profile_path_(profile_path), | 278 profile_path_(profile_path), |
281 sandbox_file_util_( | 279 sandbox_file_util_( |
282 new ObfuscatedFileSystemFileUtil( | 280 new ObfuscatedFileUtil( |
283 profile_path.Append(kNewFileSystemDirectory), | 281 profile_path.Append(kNewFileSystemDirectory), |
284 QuotaFileUtil::CreateDefault())) { | 282 QuotaFileUtil::CreateDefault())) { |
285 } | 283 } |
286 | 284 |
287 SandboxMountPointProvider::~SandboxMountPointProvider() { | 285 SandboxMountPointProvider::~SandboxMountPointProvider() { |
288 if (!file_message_loop_->BelongsToCurrentThread()) | 286 if (!file_message_loop_->BelongsToCurrentThread()) |
289 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); | 287 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); |
290 } | 288 } |
291 | 289 |
292 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, | 290 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, |
293 FileSystemType type, | 291 FileSystemType type, |
294 const FilePath& unused) { | 292 const FilePath& unused) { |
295 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent) | 293 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent) |
296 return false; | 294 return false; |
297 // We essentially depend on quota to do our access controls. | 295 // We essentially depend on quota to do our access controls. |
298 return path_manager_->IsAllowedScheme(origin_url); | 296 return path_manager_->IsAllowedScheme(origin_url); |
299 } | 297 } |
300 | 298 |
301 class SandboxMountPointProvider::GetFileSystemRootPathTask | 299 class SandboxMountPointProvider::GetFileSystemRootPathTask |
302 : public base::RefCountedThreadSafe< | 300 : public base::RefCountedThreadSafe< |
303 SandboxMountPointProvider::GetFileSystemRootPathTask> { | 301 SandboxMountPointProvider::GetFileSystemRootPathTask> { |
304 public: | 302 public: |
305 GetFileSystemRootPathTask( | 303 GetFileSystemRootPathTask( |
306 scoped_refptr<base::MessageLoopProxy> file_message_loop, | 304 scoped_refptr<base::MessageLoopProxy> file_message_loop, |
307 const GURL& origin_url, | 305 const GURL& origin_url, |
308 FileSystemType type, | 306 FileSystemType type, |
309 ObfuscatedFileSystemFileUtil* file_util, | 307 ObfuscatedFileUtil* file_util, |
310 const FilePath& old_base_path, | 308 const FilePath& old_base_path, |
311 FileSystemPathManager::GetRootPathCallback* callback) | 309 FileSystemPathManager::GetRootPathCallback* callback) |
312 : file_message_loop_(file_message_loop), | 310 : file_message_loop_(file_message_loop), |
313 origin_message_loop_proxy_( | 311 origin_message_loop_proxy_( |
314 base::MessageLoopProxy::current()), | 312 base::MessageLoopProxy::current()), |
315 origin_url_(origin_url), | 313 origin_url_(origin_url), |
316 type_(type), | 314 type_(type), |
317 file_util_(file_util), | 315 file_util_(file_util), |
318 old_base_path_(old_base_path), | 316 old_base_path_(old_base_path), |
319 callback_(callback) { | 317 callback_(callback) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 DCHECK(!type_string.empty()); | 351 DCHECK(!type_string.empty()); |
354 std::string name = origin_identifier + ":" + type_string; | 352 std::string name = origin_identifier + ":" + type_string; |
355 callback_->Run(!root_path.empty(), root_path, name); | 353 callback_->Run(!root_path.empty(), root_path, name); |
356 callback_.reset(); | 354 callback_.reset(); |
357 } | 355 } |
358 | 356 |
359 scoped_refptr<base::MessageLoopProxy> file_message_loop_; | 357 scoped_refptr<base::MessageLoopProxy> file_message_loop_; |
360 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; | 358 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_; |
361 GURL origin_url_; | 359 GURL origin_url_; |
362 FileSystemType type_; | 360 FileSystemType type_; |
363 scoped_refptr<ObfuscatedFileSystemFileUtil> file_util_; | 361 scoped_refptr<ObfuscatedFileUtil> file_util_; |
364 FilePath old_base_path_; | 362 FilePath old_base_path_; |
365 scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_; | 363 scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_; |
366 }; | 364 }; |
367 | 365 |
368 FilePath SandboxMountPointProvider::old_base_path() const { | 366 FilePath SandboxMountPointProvider::old_base_path() const { |
369 return profile_path_.Append(kOldFileSystemDirectory); | 367 return profile_path_.Append(kOldFileSystemDirectory); |
370 } | 368 } |
371 | 369 |
372 FilePath SandboxMountPointProvider::new_base_path() const { | 370 FilePath SandboxMountPointProvider::new_base_path() const { |
373 return profile_path_.Append(kNewFileSystemDirectory); | 371 return profile_path_.Append(kNewFileSystemDirectory); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( | 541 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( |
544 sandbox_file_util_->CreateFileEnumerator(&context, FilePath())); | 542 sandbox_file_util_->CreateFileEnumerator(&context, FilePath())); |
545 | 543 |
546 FilePath file_path_each; | 544 FilePath file_path_each; |
547 int64 usage = 0; | 545 int64 usage = 0; |
548 | 546 |
549 while (!(file_path_each = enumerator->Next()).empty()) { | 547 while (!(file_path_each = enumerator->Next()).empty()) { |
550 base::PlatformFileInfo file_info; | 548 base::PlatformFileInfo file_info; |
551 FilePath platform_file_path; | 549 FilePath platform_file_path; |
552 usage += enumerator->Size(); | 550 usage += enumerator->Size(); |
553 usage += ObfuscatedFileSystemFileUtil::ComputeFilePathCost(file_path_each); | 551 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); |
554 } | 552 } |
555 // This clears the dirty flag too. | 553 // This clears the dirty flag too. |
556 FileSystemUsageCache::UpdateUsage(usage_file_path, usage); | 554 FileSystemUsageCache::UpdateUsage(usage_file_path, usage); |
557 return usage; | 555 return usage; |
558 } | 556 } |
559 | 557 |
560 void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread( | 558 void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread( |
561 QuotaManagerProxy* proxy, const GURL& origin_url, | 559 QuotaManagerProxy* proxy, const GURL& origin_url, |
562 fileapi::FileSystemType type) { | 560 fileapi::FileSystemType type) { |
563 DCHECK(type == fileapi::kFileSystemTypeTemporary || | 561 DCHECK(type == fileapi::kFileSystemTypeTemporary || |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 | 607 |
610 void SandboxMountPointProvider::InvalidateUsageCache( | 608 void SandboxMountPointProvider::InvalidateUsageCache( |
611 const GURL& origin_url, fileapi::FileSystemType type) { | 609 const GURL& origin_url, fileapi::FileSystemType type) { |
612 DCHECK(type == fileapi::kFileSystemTypeTemporary || | 610 DCHECK(type == fileapi::kFileSystemTypeTemporary || |
613 type == fileapi::kFileSystemTypePersistent); | 611 type == fileapi::kFileSystemTypePersistent); |
614 FilePath usage_file_path = GetUsageCachePathForOriginAndType( | 612 FilePath usage_file_path = GetUsageCachePathForOriginAndType( |
615 origin_url, type); | 613 origin_url, type); |
616 FileSystemUsageCache::IncrementDirty(usage_file_path); | 614 FileSystemUsageCache::IncrementDirty(usage_file_path); |
617 } | 615 } |
618 | 616 |
619 FileSystemFileUtil* SandboxMountPointProvider::GetFileSystemFileUtil() { | 617 FileSystemFileUtil* SandboxMountPointProvider::GetFileUtil() { |
620 return sandbox_file_util_.get(); | 618 return sandbox_file_util_.get(); |
621 } | 619 } |
622 | 620 |
623 FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType( | 621 FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType( |
624 const GURL& origin_url, fileapi::FileSystemType type) const { | 622 const GURL& origin_url, fileapi::FileSystemType type) const { |
625 FilePath base_path = | 623 FilePath base_path = |
626 GetBaseDirectoryForOriginAndType(origin_url, type, false); | 624 GetBaseDirectoryForOriginAndType(origin_url, type, false); |
627 if (base_path.empty()) | 625 if (base_path.empty()) |
628 return FilePath(); | 626 return FilePath(); |
629 return base_path.AppendASCII(FileSystemUsageCache::kUsageFileName); | 627 return base_path.AppendASCII(FileSystemUsageCache::kUsageFileName); |
(...skipping 18 matching lines...) Expand all Loading... |
648 | 646 |
649 // Creates the root directory. | 647 // Creates the root directory. |
650 root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url)); | 648 root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url)); |
651 if (!file_util::CreateDirectory(root)) | 649 if (!file_util::CreateDirectory(root)) |
652 return FilePath(); | 650 return FilePath(); |
653 | 651 |
654 return root; | 652 return root; |
655 } | 653 } |
656 | 654 |
657 } // namespace fileapi | 655 } // namespace fileapi |
OLD | NEW |