| 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/obfuscated_file_system_file_util.h" | 5 #include "webkit/fileapi/obfuscated_file_system_file_util.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <string> |
| 8 #include <vector> | 9 #include <vector> |
| 9 | 10 |
| 10 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 11 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 15 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
| 16 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
| 17 #include "base/sys_string_conversions.h" | 18 #include "base/sys_string_conversions.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 43 bool IsRootDirectory(const FilePath& virtual_path) { | 44 bool IsRootDirectory(const FilePath& virtual_path) { |
| 44 return (virtual_path.empty() || | 45 return (virtual_path.empty() || |
| 45 virtual_path.value() == FILE_PATH_LITERAL("/")); | 46 virtual_path.value() == FILE_PATH_LITERAL("/")); |
| 46 } | 47 } |
| 47 | 48 |
| 48 // Costs computed as per crbug.com/86114, based on the LevelDB implementation of | 49 // Costs computed as per crbug.com/86114, based on the LevelDB implementation of |
| 49 // path storage under Linux. It's not clear if that will differ on Windows, on | 50 // path storage under Linux. It's not clear if that will differ on Windows, on |
| 50 // which FilePath uses wide chars [since they're converted to UTF-8 for storage | 51 // which FilePath uses wide chars [since they're converted to UTF-8 for storage |
| 51 // anyway], but as long as the cost is high enough that one can't cheat on quota | 52 // anyway], but as long as the cost is high enough that one can't cheat on quota |
| 52 // by storing data in paths, it doesn't need to be all that accurate. | 53 // by storing data in paths, it doesn't need to be all that accurate. |
| 53 const int64 kPathCreationQuotaCost = 146; // Bytes per inode, basically. | 54 const int64 kPathCreationQuotaCost = 146; // Bytes per inode, basically. |
| 54 const int64 kPathByteQuotaCost = 2; // Bytes per byte of path length in UTF-8. | 55 const int64 kPathByteQuotaCost = 2; // Bytes per byte of path length in UTF-8. |
| 55 | 56 |
| 56 int64 GetPathQuotaUsage( | 57 int64 GetPathQuotaUsage( |
| 57 int growth_in_number_of_paths, | 58 int growth_in_number_of_paths, |
| 58 int64 growth_in_bytes_of_path_length) { | 59 int64 growth_in_bytes_of_path_length) { |
| 59 return growth_in_number_of_paths * kPathCreationQuotaCost + | 60 return growth_in_number_of_paths * kPathCreationQuotaCost + |
| 60 growth_in_bytes_of_path_length * kPathByteQuotaCost; | 61 growth_in_bytes_of_path_length * kPathByteQuotaCost; |
| 61 } | 62 } |
| 62 | 63 |
| 63 bool AllocateQuotaForPath( | 64 bool AllocateQuotaForPath( |
| 64 fileapi::FileSystemOperationContext* context, | 65 fileapi::FileSystemOperationContext* context, |
| 65 int growth_in_number_of_paths, | 66 int growth_in_number_of_paths, |
| 66 int64 growth_in_bytes_of_path_length) { | 67 int64 growth_in_bytes_of_path_length) { |
| 67 int64 growth = GetPathQuotaUsage(growth_in_number_of_paths, | 68 int64 growth = GetPathQuotaUsage(growth_in_number_of_paths, |
| 68 growth_in_bytes_of_path_length); | 69 growth_in_bytes_of_path_length); |
| 69 int64 new_quota = context->allowed_bytes_growth() - growth; | 70 int64 new_quota = context->allowed_bytes_growth() - growth; |
| 70 | 71 |
| 71 if (growth <= 0 || new_quota >= 0) { | 72 if (growth <= 0 || new_quota >= 0) { |
| 72 context->set_allowed_bytes_growth(new_quota); | 73 context->set_allowed_bytes_growth(new_quota); |
| 73 return true; | 74 return true; |
| 74 } | 75 } |
| 75 return false; | 76 return false; |
| 76 } | 77 } |
| 77 | 78 |
| 78 void UpdatePathQuotaUsage( | 79 void UpdatePathQuotaUsage( |
| 79 fileapi::FileSystemOperationContext* context, | 80 fileapi::FileSystemOperationContext* context, |
| 80 const GURL& origin_url, | 81 const GURL& origin_url, |
| 81 fileapi::FileSystemType type, | 82 fileapi::FileSystemType type, |
| 82 int growth_in_number_of_paths, // -1, 0, or 1 | 83 int growth_in_number_of_paths, // -1, 0, or 1 |
| 83 int64 growth_in_bytes_of_path_length) { | 84 int64 growth_in_bytes_of_path_length) { |
| 84 int64 growth = GetPathQuotaUsage(growth_in_number_of_paths, | 85 int64 growth = GetPathQuotaUsage(growth_in_number_of_paths, |
| 85 growth_in_bytes_of_path_length); | 86 growth_in_bytes_of_path_length); |
| 86 fileapi::FileSystemQuotaUtil* quota_util = | 87 fileapi::FileSystemQuotaUtil* quota_util = |
| 87 context->file_system_context()->GetQuotaUtil(type); | 88 context->file_system_context()->GetQuotaUtil(type); |
| 88 quota::QuotaManagerProxy* quota_manager_proxy = | 89 quota::QuotaManagerProxy* quota_manager_proxy = |
| 89 context->file_system_context()->quota_manager_proxy(); | 90 context->file_system_context()->quota_manager_proxy(); |
| 90 quota_util->UpdateOriginUsageOnFileThread(quota_manager_proxy, origin_url, | 91 quota_util->UpdateOriginUsageOnFileThread(quota_manager_proxy, origin_url, |
| 91 type, growth); | 92 type, growth); |
| 92 } | 93 } |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 // TODO(ericu): This could easily be made faster with help from the database. | 658 // TODO(ericu): This could easily be made faster with help from the database. |
| 658 if (!db->ListChildren(file_id, &children)) | 659 if (!db->ListChildren(file_id, &children)) |
| 659 return true; | 660 return true; |
| 660 return children.empty(); | 661 return children.empty(); |
| 661 } | 662 } |
| 662 | 663 |
| 663 class ObfuscatedFileSystemFileEnumerator | 664 class ObfuscatedFileSystemFileEnumerator |
| 664 : public FileSystemFileUtil::AbstractFileEnumerator { | 665 : public FileSystemFileUtil::AbstractFileEnumerator { |
| 665 public: | 666 public: |
| 666 ObfuscatedFileSystemFileEnumerator( | 667 ObfuscatedFileSystemFileEnumerator( |
| 667 FileSystemDirectoryDatabase* db, const FilePath& virtual_root_path) | 668 const FilePath& base_path, |
| 668 : db_(db) { | 669 FileSystemDirectoryDatabase* db, |
| 670 FileSystemOperationContext* context, |
| 671 FileSystemFileUtil* underlying_file_util, |
| 672 const FilePath& virtual_root_path) |
| 673 : base_path_(base_path), |
| 674 db_(db), |
| 675 context_(context), |
| 676 underlying_file_util_(underlying_file_util) { |
| 677 DCHECK(db_); |
| 678 DCHECK(context_); |
| 679 DCHECK(underlying_file_util_); |
| 680 |
| 669 FileId file_id; | 681 FileId file_id; |
| 670 FileInfo file_info; | 682 FileInfo file_info; |
| 671 if (!db_->GetFileWithPath(virtual_root_path, &file_id)) | 683 if (!db_->GetFileWithPath(virtual_root_path, &file_id)) |
| 672 return; | 684 return; |
| 673 if (!db_->GetFileInfo(file_id, &file_info)) | 685 if (!db_->GetFileInfo(file_id, &file_info)) |
| 674 return; | 686 return; |
| 675 if (!file_info.is_directory()) | 687 if (!file_info.is_directory()) |
| 676 return; | 688 return; |
| 677 FileRecord record = { file_id, file_info, virtual_root_path }; | 689 FileRecord record = { file_id, file_info, virtual_root_path }; |
| 678 display_queue_.push(record); | 690 display_queue_.push(record); |
| 679 Next(); // Enumerators don't include the directory itself. | 691 Next(); // Enumerators don't include the directory itself. |
| 680 } | 692 } |
| 681 | 693 |
| 682 ~ObfuscatedFileSystemFileEnumerator() {} | 694 ~ObfuscatedFileSystemFileEnumerator() {} |
| 683 | 695 |
| 684 virtual FilePath Next() { | 696 virtual FilePath Next() OVERRIDE { |
| 685 ProcessRecurseQueue(); | 697 ProcessRecurseQueue(); |
| 686 if (display_queue_.empty()) | 698 if (display_queue_.empty()) |
| 687 return FilePath(); | 699 return FilePath(); |
| 688 current_ = display_queue_.front(); | 700 current_ = display_queue_.front(); |
| 689 display_queue_.pop(); | 701 display_queue_.pop(); |
| 690 if (current_.file_info.is_directory()) | 702 if (current_.file_info.is_directory()) |
| 691 recurse_queue_.push(current_); | 703 recurse_queue_.push(current_); |
| 692 return current_.file_path; | 704 return current_.file_path; |
| 693 } | 705 } |
| 694 | 706 |
| 695 virtual bool IsDirectory() { | 707 virtual int64 Size() OVERRIDE { |
| 708 if (IsDirectory()) |
| 709 return 0; |
| 710 |
| 711 base::PlatformFileInfo file_info; |
| 712 FilePath platform_file_path; |
| 713 |
| 714 FilePath local_path = base_path_.Append(current_.file_info.data_path); |
| 715 base::PlatformFileError error = underlying_file_util_->GetFileInfo( |
| 716 context_, local_path, &file_info, &platform_file_path); |
| 717 if (error != base::PLATFORM_FILE_OK) { |
| 718 LOG(WARNING) << "Lost a backing file."; |
| 719 return 0; |
| 720 } |
| 721 return file_info.size; |
| 722 } |
| 723 |
| 724 virtual bool IsDirectory() OVERRIDE { |
| 696 return current_.file_info.is_directory(); | 725 return current_.file_info.is_directory(); |
| 697 } | 726 } |
| 698 | 727 |
| 699 private: | 728 private: |
| 700 typedef FileSystemDirectoryDatabase::FileId FileId; | 729 typedef FileSystemDirectoryDatabase::FileId FileId; |
| 701 typedef FileSystemDirectoryDatabase::FileInfo FileInfo; | 730 typedef FileSystemDirectoryDatabase::FileInfo FileInfo; |
| 702 | 731 |
| 703 struct FileRecord { | 732 struct FileRecord { |
| 704 FileId file_id; | 733 FileId file_id; |
| 705 FileInfo file_info; | 734 FileInfo file_info; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 721 return; | 750 return; |
| 722 child.file_path = directory.file_path.Append(child.file_info.name); | 751 child.file_path = directory.file_path.Append(child.file_info.name); |
| 723 display_queue_.push(child); | 752 display_queue_.push(child); |
| 724 } | 753 } |
| 725 } | 754 } |
| 726 } | 755 } |
| 727 | 756 |
| 728 std::queue<FileRecord> display_queue_; | 757 std::queue<FileRecord> display_queue_; |
| 729 std::queue<FileRecord> recurse_queue_; | 758 std::queue<FileRecord> recurse_queue_; |
| 730 FileRecord current_; | 759 FileRecord current_; |
| 760 FilePath base_path_; |
| 731 FileSystemDirectoryDatabase* db_; | 761 FileSystemDirectoryDatabase* db_; |
| 762 FileSystemOperationContext* context_; |
| 763 FileSystemFileUtil* underlying_file_util_; |
| 732 }; | 764 }; |
| 733 | 765 |
| 734 class ObfuscatedFileSystemOriginEnumerator | 766 class ObfuscatedFileSystemOriginEnumerator |
| 735 : public ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator { | 767 : public ObfuscatedFileSystemFileUtil::AbstractOriginEnumerator { |
| 736 public: | 768 public: |
| 737 typedef FileSystemOriginDatabase::OriginRecord OriginRecord; | 769 typedef FileSystemOriginDatabase::OriginRecord OriginRecord; |
| 738 ObfuscatedFileSystemOriginEnumerator( | 770 ObfuscatedFileSystemOriginEnumerator( |
| 739 FileSystemOriginDatabase* origin_database, | 771 FileSystemOriginDatabase* origin_database, |
| 740 const FilePath& base_path) | 772 const FilePath& base_path) |
| 741 : base_path_(base_path) { | 773 : base_path_(base_path) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 } | 818 } |
| 787 | 819 |
| 788 FileSystemFileUtil::AbstractFileEnumerator* | 820 FileSystemFileUtil::AbstractFileEnumerator* |
| 789 ObfuscatedFileSystemFileUtil::CreateFileEnumerator( | 821 ObfuscatedFileSystemFileUtil::CreateFileEnumerator( |
| 790 FileSystemOperationContext* context, | 822 FileSystemOperationContext* context, |
| 791 const FilePath& root_path) { | 823 const FilePath& root_path) { |
| 792 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( | 824 FileSystemDirectoryDatabase* db = GetDirectoryDatabase( |
| 793 context->src_origin_url(), context->src_type(), false); | 825 context->src_origin_url(), context->src_type(), false); |
| 794 if (!db) | 826 if (!db) |
| 795 return new FileSystemFileUtil::EmptyFileEnumerator(); | 827 return new FileSystemFileUtil::EmptyFileEnumerator(); |
| 796 return new ObfuscatedFileSystemFileEnumerator(db, root_path); | 828 return new ObfuscatedFileSystemFileEnumerator( |
| 829 GetDirectoryForOriginAndType(context->src_origin_url(), |
| 830 context->src_type(), false), |
| 831 db, |
| 832 context, |
| 833 underlying_file_util_.get(), |
| 834 root_path); |
| 797 } | 835 } |
| 798 | 836 |
| 799 PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfoInternal( | 837 PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfoInternal( |
| 800 FileSystemDirectoryDatabase* db, | 838 FileSystemDirectoryDatabase* db, |
| 801 FileSystemOperationContext* context, | 839 FileSystemOperationContext* context, |
| 802 FileId file_id, | 840 FileId file_id, |
| 803 FileInfo* local_info, | 841 FileInfo* local_info, |
| 804 base::PlatformFileInfo* file_info, | 842 base::PlatformFileInfo* file_info, |
| 805 FilePath* platform_file_path) { | 843 FilePath* platform_file_path) { |
| 806 DCHECK(db); | 844 DCHECK(db); |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 return false; | 1215 return false; |
| 1178 } | 1216 } |
| 1179 origin_database_.reset( | 1217 origin_database_.reset( |
| 1180 new FileSystemOriginDatabase( | 1218 new FileSystemOriginDatabase( |
| 1181 file_system_directory_.AppendASCII(kOriginDatabaseName))); | 1219 file_system_directory_.AppendASCII(kOriginDatabaseName))); |
| 1182 } | 1220 } |
| 1183 return true; | 1221 return true; |
| 1184 } | 1222 } |
| 1185 | 1223 |
| 1186 } // namespace fileapi | 1224 } // namespace fileapi |
| OLD | NEW |