| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/browser/database/database_tracker.h" | 5 #include "webkit/browser/database/database_tracker.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/files/file.h" | 13 #include "base/files/file.h" |
| 14 #include "base/files/file_enumerator.h" | 14 #include "base/files/file_enumerator.h" |
| 15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
| 16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 #include "sql/connection.h" | 19 #include "sql/connection.h" |
| 20 #include "sql/meta_table.h" | 20 #include "sql/meta_table.h" |
| 21 #include "sql/transaction.h" | 21 #include "sql/transaction.h" |
| 22 #include "third_party/sqlite/sqlite3.h" | 22 #include "third_party/sqlite/sqlite3.h" |
| 23 #include "webkit/browser/database/database_quota_client.h" | 23 #include "webkit/browser/database/database_quota_client.h" |
| 24 #include "webkit/browser/database/database_util.h" | 24 #include "webkit/browser/database/database_util.h" |
| 25 #include "webkit/browser/database/databases_table.h" | 25 #include "webkit/browser/database/databases_table.h" |
| 26 #include "webkit/browser/quota/quota_manager_proxy.h" | 26 #include "webkit/browser/quota/quota_manager_proxy.h" |
| 27 #include "webkit/browser/quota/special_storage_policy.h" | 27 #include "webkit/browser/quota/special_storage_policy.h" |
| 28 #include "webkit/common/database/database_identifier.h" | 28 #include "webkit/common/database/database_identifier.h" |
| 29 | 29 |
| 30 namespace webkit_database { | 30 namespace storage { |
| 31 | 31 |
| 32 const base::FilePath::CharType kDatabaseDirectoryName[] = | 32 const base::FilePath::CharType kDatabaseDirectoryName[] = |
| 33 FILE_PATH_LITERAL("databases"); | 33 FILE_PATH_LITERAL("databases"); |
| 34 const base::FilePath::CharType kIncognitoDatabaseDirectoryName[] = | 34 const base::FilePath::CharType kIncognitoDatabaseDirectoryName[] = |
| 35 FILE_PATH_LITERAL("databases-incognito"); | 35 FILE_PATH_LITERAL("databases-incognito"); |
| 36 const base::FilePath::CharType kTrackerDatabaseFileName[] = | 36 const base::FilePath::CharType kTrackerDatabaseFileName[] = |
| 37 FILE_PATH_LITERAL("Databases.db"); | 37 FILE_PATH_LITERAL("Databases.db"); |
| 38 static const int kCurrentVersion = 2; | 38 static const int kCurrentVersion = 2; |
| 39 static const int kCompatibleVersion = 1; | 39 static const int kCompatibleVersion = 1; |
| 40 | 40 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 return it->second.second; | 75 return it->second.second; |
| 76 return base::string16(); | 76 return base::string16(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 OriginInfo::OriginInfo(const std::string& origin_identifier, int64 total_size) | 79 OriginInfo::OriginInfo(const std::string& origin_identifier, int64 total_size) |
| 80 : origin_identifier_(origin_identifier), total_size_(total_size) {} | 80 : origin_identifier_(origin_identifier), total_size_(total_size) {} |
| 81 | 81 |
| 82 DatabaseTracker::DatabaseTracker( | 82 DatabaseTracker::DatabaseTracker( |
| 83 const base::FilePath& profile_path, | 83 const base::FilePath& profile_path, |
| 84 bool is_incognito, | 84 bool is_incognito, |
| 85 quota::SpecialStoragePolicy* special_storage_policy, | 85 storage::SpecialStoragePolicy* special_storage_policy, |
| 86 quota::QuotaManagerProxy* quota_manager_proxy, | 86 storage::QuotaManagerProxy* quota_manager_proxy, |
| 87 base::MessageLoopProxy* db_tracker_thread) | 87 base::MessageLoopProxy* db_tracker_thread) |
| 88 : is_initialized_(false), | 88 : is_initialized_(false), |
| 89 is_incognito_(is_incognito), | 89 is_incognito_(is_incognito), |
| 90 force_keep_session_state_(false), | 90 force_keep_session_state_(false), |
| 91 shutting_down_(false), | 91 shutting_down_(false), |
| 92 profile_path_(profile_path), | 92 profile_path_(profile_path), |
| 93 db_dir_(is_incognito_ | 93 db_dir_(is_incognito_ |
| 94 ? profile_path_.Append(kIncognitoDatabaseDirectoryName) | 94 ? profile_path_.Append(kIncognitoDatabaseDirectoryName) |
| 95 : profile_path_.Append(kDatabaseDirectoryName)), | 95 : profile_path_.Append(kDatabaseDirectoryName)), |
| 96 db_(new sql::Connection()), | 96 db_(new sql::Connection()), |
| (...skipping 17 matching lines...) Expand all Loading... |
| 114 const base::string16& database_description, | 114 const base::string16& database_description, |
| 115 int64 estimated_size, | 115 int64 estimated_size, |
| 116 int64* database_size) { | 116 int64* database_size) { |
| 117 if (shutting_down_ || !LazyInit()) { | 117 if (shutting_down_ || !LazyInit()) { |
| 118 *database_size = 0; | 118 *database_size = 0; |
| 119 return; | 119 return; |
| 120 } | 120 } |
| 121 | 121 |
| 122 if (quota_manager_proxy_.get()) | 122 if (quota_manager_proxy_.get()) |
| 123 quota_manager_proxy_->NotifyStorageAccessed( | 123 quota_manager_proxy_->NotifyStorageAccessed( |
| 124 quota::QuotaClient::kDatabase, | 124 storage::QuotaClient::kDatabase, |
| 125 webkit_database::GetOriginFromIdentifier(origin_identifier), | 125 storage::GetOriginFromIdentifier(origin_identifier), |
| 126 quota::kStorageTypeTemporary); | 126 storage::kStorageTypeTemporary); |
| 127 | 127 |
| 128 InsertOrUpdateDatabaseDetails(origin_identifier, database_name, | 128 InsertOrUpdateDatabaseDetails(origin_identifier, database_name, |
| 129 database_description, estimated_size); | 129 database_description, estimated_size); |
| 130 if (database_connections_.AddConnection(origin_identifier, database_name)) { | 130 if (database_connections_.AddConnection(origin_identifier, database_name)) { |
| 131 *database_size = SeedOpenDatabaseInfo(origin_identifier, | 131 *database_size = SeedOpenDatabaseInfo(origin_identifier, |
| 132 database_name, | 132 database_name, |
| 133 database_description); | 133 database_description); |
| 134 return; | 134 return; |
| 135 } | 135 } |
| 136 *database_size = UpdateOpenDatabaseInfoAndNotify(origin_identifier, | 136 *database_size = UpdateOpenDatabaseInfoAndNotify(origin_identifier, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 149 const base::string16& database_name) { | 149 const base::string16& database_name) { |
| 150 if (database_connections_.IsEmpty()) { | 150 if (database_connections_.IsEmpty()) { |
| 151 DCHECK(!is_initialized_); | 151 DCHECK(!is_initialized_); |
| 152 return; | 152 return; |
| 153 } | 153 } |
| 154 | 154 |
| 155 // We call NotifiyStorageAccessed when a db is opened and also when | 155 // We call NotifiyStorageAccessed when a db is opened and also when |
| 156 // closed because we don't call it for read while open. | 156 // closed because we don't call it for read while open. |
| 157 if (quota_manager_proxy_.get()) | 157 if (quota_manager_proxy_.get()) |
| 158 quota_manager_proxy_->NotifyStorageAccessed( | 158 quota_manager_proxy_->NotifyStorageAccessed( |
| 159 quota::QuotaClient::kDatabase, | 159 storage::QuotaClient::kDatabase, |
| 160 webkit_database::GetOriginFromIdentifier(origin_identifier), | 160 storage::GetOriginFromIdentifier(origin_identifier), |
| 161 quota::kStorageTypeTemporary); | 161 storage::kStorageTypeTemporary); |
| 162 | 162 |
| 163 UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name); | 163 UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name); |
| 164 if (database_connections_.RemoveConnection(origin_identifier, database_name)) | 164 if (database_connections_.RemoveConnection(origin_identifier, database_name)) |
| 165 DeleteDatabaseIfNeeded(origin_identifier, database_name); | 165 DeleteDatabaseIfNeeded(origin_identifier, database_name); |
| 166 } | 166 } |
| 167 | 167 |
| 168 void DatabaseTracker::HandleSqliteError( | 168 void DatabaseTracker::HandleSqliteError( |
| 169 const std::string& origin_identifier, | 169 const std::string& origin_identifier, |
| 170 const base::string16& database_name, | 170 const base::string16& database_name, |
| 171 int error) { | 171 int error) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 ? GetDBFileSize(origin_identifier, database_name) | 354 ? GetDBFileSize(origin_identifier, database_name) |
| 355 : 0; | 355 : 0; |
| 356 | 356 |
| 357 // Try to delete the file on the hard drive. | 357 // Try to delete the file on the hard drive. |
| 358 base::FilePath db_file = GetFullDBFilePath(origin_identifier, database_name); | 358 base::FilePath db_file = GetFullDBFilePath(origin_identifier, database_name); |
| 359 if (!sql::Connection::Delete(db_file)) | 359 if (!sql::Connection::Delete(db_file)) |
| 360 return false; | 360 return false; |
| 361 | 361 |
| 362 if (quota_manager_proxy_.get() && db_file_size) | 362 if (quota_manager_proxy_.get() && db_file_size) |
| 363 quota_manager_proxy_->NotifyStorageModified( | 363 quota_manager_proxy_->NotifyStorageModified( |
| 364 quota::QuotaClient::kDatabase, | 364 storage::QuotaClient::kDatabase, |
| 365 webkit_database::GetOriginFromIdentifier(origin_identifier), | 365 storage::GetOriginFromIdentifier(origin_identifier), |
| 366 quota::kStorageTypeTemporary, | 366 storage::kStorageTypeTemporary, |
| 367 -db_file_size); | 367 -db_file_size); |
| 368 | 368 |
| 369 // Clean up the main database and invalidate the cached record. | 369 // Clean up the main database and invalidate the cached record. |
| 370 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); | 370 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); |
| 371 origins_info_map_.erase(origin_identifier); | 371 origins_info_map_.erase(origin_identifier); |
| 372 | 372 |
| 373 std::vector<DatabaseDetails> details; | 373 std::vector<DatabaseDetails> details; |
| 374 if (databases_table_->GetAllDatabaseDetailsForOriginIdentifier( | 374 if (databases_table_->GetAllDatabaseDetailsForOriginIdentifier( |
| 375 origin_identifier, &details) && details.empty()) { | 375 origin_identifier, &details) && details.empty()) { |
| 376 // Try to delete the origin in case this was the last database. | 376 // Try to delete the origin in case this was the last database. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 base::FilePath new_file = new_origin_dir.Append(database.BaseName()); | 414 base::FilePath new_file = new_origin_dir.Append(database.BaseName()); |
| 415 base::Move(database, new_file); | 415 base::Move(database, new_file); |
| 416 } | 416 } |
| 417 base::DeleteFile(origin_dir, true); | 417 base::DeleteFile(origin_dir, true); |
| 418 base::DeleteFile(new_origin_dir, true); // might fail on windows. | 418 base::DeleteFile(new_origin_dir, true); // might fail on windows. |
| 419 | 419 |
| 420 databases_table_->DeleteOriginIdentifier(origin_identifier); | 420 databases_table_->DeleteOriginIdentifier(origin_identifier); |
| 421 | 421 |
| 422 if (quota_manager_proxy_.get() && deleted_size) { | 422 if (quota_manager_proxy_.get() && deleted_size) { |
| 423 quota_manager_proxy_->NotifyStorageModified( | 423 quota_manager_proxy_->NotifyStorageModified( |
| 424 quota::QuotaClient::kDatabase, | 424 storage::QuotaClient::kDatabase, |
| 425 webkit_database::GetOriginFromIdentifier(origin_identifier), | 425 storage::GetOriginFromIdentifier(origin_identifier), |
| 426 quota::kStorageTypeTemporary, | 426 storage::kStorageTypeTemporary, |
| 427 -deleted_size); | 427 -deleted_size); |
| 428 } | 428 } |
| 429 | 429 |
| 430 return true; | 430 return true; |
| 431 } | 431 } |
| 432 | 432 |
| 433 bool DatabaseTracker::IsDatabaseScheduledForDeletion( | 433 bool DatabaseTracker::IsDatabaseScheduledForDeletion( |
| 434 const std::string& origin_identifier, | 434 const std::string& origin_identifier, |
| 435 const base::string16& database_name) { | 435 const base::string16& database_name) { |
| 436 DatabaseSet::iterator it = dbs_to_be_deleted_.find(origin_identifier); | 436 DatabaseSet::iterator it = dbs_to_be_deleted_.find(origin_identifier); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 int64 old_size = database_connections_.GetOpenDatabaseSize(origin_id, name); | 601 int64 old_size = database_connections_.GetOpenDatabaseSize(origin_id, name); |
| 602 CachedOriginInfo* info = MaybeGetCachedOriginInfo(origin_id, false); | 602 CachedOriginInfo* info = MaybeGetCachedOriginInfo(origin_id, false); |
| 603 if (info && opt_description) | 603 if (info && opt_description) |
| 604 info->SetDatabaseDescription(name, *opt_description); | 604 info->SetDatabaseDescription(name, *opt_description); |
| 605 if (old_size != new_size) { | 605 if (old_size != new_size) { |
| 606 database_connections_.SetOpenDatabaseSize(origin_id, name, new_size); | 606 database_connections_.SetOpenDatabaseSize(origin_id, name, new_size); |
| 607 if (info) | 607 if (info) |
| 608 info->SetDatabaseSize(name, new_size); | 608 info->SetDatabaseSize(name, new_size); |
| 609 if (quota_manager_proxy_.get()) | 609 if (quota_manager_proxy_.get()) |
| 610 quota_manager_proxy_->NotifyStorageModified( | 610 quota_manager_proxy_->NotifyStorageModified( |
| 611 quota::QuotaClient::kDatabase, | 611 storage::QuotaClient::kDatabase, |
| 612 webkit_database::GetOriginFromIdentifier(origin_id), | 612 storage::GetOriginFromIdentifier(origin_id), |
| 613 quota::kStorageTypeTemporary, | 613 storage::kStorageTypeTemporary, |
| 614 new_size - old_size); | 614 new_size - old_size); |
| 615 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseSizeChanged( | 615 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseSizeChanged( |
| 616 origin_id, name, new_size)); | 616 origin_id, name, new_size)); |
| 617 } | 617 } |
| 618 return new_size; | 618 return new_size; |
| 619 } | 619 } |
| 620 | 620 |
| 621 void DatabaseTracker::ScheduleDatabaseForDeletion( | 621 void DatabaseTracker::ScheduleDatabaseForDeletion( |
| 622 const std::string& origin_identifier, | 622 const std::string& origin_identifier, |
| 623 const base::string16& database_name) { | 623 const base::string16& database_name) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 | 673 |
| 674 std::vector<std::string> origins_identifiers; | 674 std::vector<std::string> origins_identifiers; |
| 675 if (!databases_table_->GetAllOriginIdentifiers(&origins_identifiers)) | 675 if (!databases_table_->GetAllOriginIdentifiers(&origins_identifiers)) |
| 676 return net::ERR_FAILED; | 676 return net::ERR_FAILED; |
| 677 int rv = net::OK; | 677 int rv = net::OK; |
| 678 for (std::vector<std::string>::const_iterator ori = | 678 for (std::vector<std::string>::const_iterator ori = |
| 679 origins_identifiers.begin(); | 679 origins_identifiers.begin(); |
| 680 ori != origins_identifiers.end(); ++ori) { | 680 ori != origins_identifiers.end(); ++ori) { |
| 681 if (special_storage_policy_.get() && | 681 if (special_storage_policy_.get() && |
| 682 special_storage_policy_->IsStorageProtected( | 682 special_storage_policy_->IsStorageProtected( |
| 683 webkit_database::GetOriginFromIdentifier(*ori))) { | 683 storage::GetOriginFromIdentifier(*ori))) { |
| 684 continue; | 684 continue; |
| 685 } | 685 } |
| 686 | 686 |
| 687 std::vector<DatabaseDetails> details; | 687 std::vector<DatabaseDetails> details; |
| 688 if (!databases_table_-> | 688 if (!databases_table_-> |
| 689 GetAllDatabaseDetailsForOriginIdentifier(*ori, &details)) | 689 GetAllDatabaseDetailsForOriginIdentifier(*ori, &details)) |
| 690 rv = net::ERR_FAILED; | 690 rv = net::ERR_FAILED; |
| 691 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); | 691 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); |
| 692 db != details.end(); ++db) { | 692 db != details.end(); ++db) { |
| 693 base::FilePath db_file = GetFullDBFilePath(*ori, db->database_name); | 693 base::FilePath db_file = GetFullDBFilePath(*ori, db->database_name); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 | 810 |
| 811 if (!LazyInit()) | 811 if (!LazyInit()) |
| 812 return; | 812 return; |
| 813 | 813 |
| 814 std::vector<std::string> origin_identifiers; | 814 std::vector<std::string> origin_identifiers; |
| 815 GetAllOriginIdentifiers(&origin_identifiers); | 815 GetAllOriginIdentifiers(&origin_identifiers); |
| 816 | 816 |
| 817 for (std::vector<std::string>::iterator origin = | 817 for (std::vector<std::string>::iterator origin = |
| 818 origin_identifiers.begin(); | 818 origin_identifiers.begin(); |
| 819 origin != origin_identifiers.end(); ++origin) { | 819 origin != origin_identifiers.end(); ++origin) { |
| 820 GURL origin_url = webkit_database::GetOriginFromIdentifier(*origin); | 820 GURL origin_url = storage::GetOriginFromIdentifier(*origin); |
| 821 if (!special_storage_policy_->IsStorageSessionOnly(origin_url)) | 821 if (!special_storage_policy_->IsStorageSessionOnly(origin_url)) |
| 822 continue; | 822 continue; |
| 823 if (special_storage_policy_->IsStorageProtected(origin_url)) | 823 if (special_storage_policy_->IsStorageProtected(origin_url)) |
| 824 continue; | 824 continue; |
| 825 webkit_database::OriginInfo origin_info; | 825 storage::OriginInfo origin_info; |
| 826 std::vector<base::string16> databases; | 826 std::vector<base::string16> databases; |
| 827 GetOriginInfo(*origin, &origin_info); | 827 GetOriginInfo(*origin, &origin_info); |
| 828 origin_info.GetAllDatabaseNames(&databases); | 828 origin_info.GetAllDatabaseNames(&databases); |
| 829 | 829 |
| 830 for (std::vector<base::string16>::iterator database = databases.begin(); | 830 for (std::vector<base::string16>::iterator database = databases.begin(); |
| 831 database != databases.end(); ++database) { | 831 database != databases.end(); ++database) { |
| 832 base::File file(GetFullDBFilePath(*origin, *database), | 832 base::File file(GetFullDBFilePath(*origin, *database), |
| 833 base::File::FLAG_OPEN_ALWAYS | | 833 base::File::FLAG_OPEN_ALWAYS | |
| 834 base::File::FLAG_SHARE_DELETE | | 834 base::File::FLAG_SHARE_DELETE | |
| 835 base::File::FLAG_DELETE_ON_CLOSE | | 835 base::File::FLAG_DELETE_ON_CLOSE | |
| (...skipping 23 matching lines...) Expand all Loading... |
| 859 DCHECK(db_tracker_thread_.get()); | 859 DCHECK(db_tracker_thread_.get()); |
| 860 if (!db_tracker_thread_->BelongsToCurrentThread()) { | 860 if (!db_tracker_thread_->BelongsToCurrentThread()) { |
| 861 db_tracker_thread_->PostTask( | 861 db_tracker_thread_->PostTask( |
| 862 FROM_HERE, | 862 FROM_HERE, |
| 863 base::Bind(&DatabaseTracker::SetForceKeepSessionState, this)); | 863 base::Bind(&DatabaseTracker::SetForceKeepSessionState, this)); |
| 864 return; | 864 return; |
| 865 } | 865 } |
| 866 force_keep_session_state_ = true; | 866 force_keep_session_state_ = true; |
| 867 } | 867 } |
| 868 | 868 |
| 869 } // namespace webkit_database | 869 } // namespace storage |
| OLD | NEW |