| 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 "storage/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 "storage/browser/database/database_quota_client.h" |
| 24 #include "webkit/browser/database/database_util.h" | 24 #include "storage/browser/database/database_util.h" |
| 25 #include "webkit/browser/database/databases_table.h" | 25 #include "storage/browser/database/databases_table.h" |
| 26 #include "webkit/browser/quota/quota_manager_proxy.h" | 26 #include "storage/browser/quota/quota_manager_proxy.h" |
| 27 #include "webkit/browser/quota/special_storage_policy.h" | 27 #include "storage/browser/quota/special_storage_policy.h" |
| 28 #include "webkit/common/database/database_identifier.h" | 28 #include "storage/common/database/database_identifier.h" |
| 29 | 29 |
| 30 namespace webkit_database { | 30 namespace webkit_database { |
| 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 |
| 41 const base::FilePath::CharType kTemporaryDirectoryPrefix[] = | 41 const base::FilePath::CharType kTemporaryDirectoryPrefix[] = |
| 42 FILE_PATH_LITERAL("DeleteMe"); | 42 FILE_PATH_LITERAL("DeleteMe"); |
| 43 const base::FilePath::CharType kTemporaryDirectoryPattern[] = | 43 const base::FilePath::CharType kTemporaryDirectoryPattern[] = |
| 44 FILE_PATH_LITERAL("DeleteMe*"); | 44 FILE_PATH_LITERAL("DeleteMe*"); |
| 45 | 45 |
| 46 OriginInfo::OriginInfo() | 46 OriginInfo::OriginInfo() : total_size_(0) { |
| 47 : total_size_(0) {} | 47 } |
| 48 | 48 |
| 49 OriginInfo::OriginInfo(const OriginInfo& origin_info) | 49 OriginInfo::OriginInfo(const OriginInfo& origin_info) |
| 50 : origin_identifier_(origin_info.origin_identifier_), | 50 : origin_identifier_(origin_info.origin_identifier_), |
| 51 total_size_(origin_info.total_size_), | 51 total_size_(origin_info.total_size_), |
| 52 database_info_(origin_info.database_info_) {} | 52 database_info_(origin_info.database_info_) { |
| 53 } |
| 53 | 54 |
| 54 OriginInfo::~OriginInfo() {} | 55 OriginInfo::~OriginInfo() { |
| 56 } |
| 55 | 57 |
| 56 void OriginInfo::GetAllDatabaseNames( | 58 void OriginInfo::GetAllDatabaseNames( |
| 57 std::vector<base::string16>* databases) const { | 59 std::vector<base::string16>* databases) const { |
| 58 for (DatabaseInfoMap::const_iterator it = database_info_.begin(); | 60 for (DatabaseInfoMap::const_iterator it = database_info_.begin(); |
| 59 it != database_info_.end(); it++) { | 61 it != database_info_.end(); |
| 62 it++) { |
| 60 databases->push_back(it->first); | 63 databases->push_back(it->first); |
| 61 } | 64 } |
| 62 } | 65 } |
| 63 | 66 |
| 64 int64 OriginInfo::GetDatabaseSize(const base::string16& database_name) const { | 67 int64 OriginInfo::GetDatabaseSize(const base::string16& database_name) const { |
| 65 DatabaseInfoMap::const_iterator it = database_info_.find(database_name); | 68 DatabaseInfoMap::const_iterator it = database_info_.find(database_name); |
| 66 if (it != database_info_.end()) | 69 if (it != database_info_.end()) |
| 67 return it->second.first; | 70 return it->second.first; |
| 68 return 0; | 71 return 0; |
| 69 } | 72 } |
| 70 | 73 |
| 71 base::string16 OriginInfo::GetDatabaseDescription( | 74 base::string16 OriginInfo::GetDatabaseDescription( |
| 72 const base::string16& database_name) const { | 75 const base::string16& database_name) const { |
| 73 DatabaseInfoMap::const_iterator it = database_info_.find(database_name); | 76 DatabaseInfoMap::const_iterator it = database_info_.find(database_name); |
| 74 if (it != database_info_.end()) | 77 if (it != database_info_.end()) |
| 75 return it->second.second; | 78 return it->second.second; |
| 76 return base::string16(); | 79 return base::string16(); |
| 77 } | 80 } |
| 78 | 81 |
| 79 OriginInfo::OriginInfo(const std::string& origin_identifier, int64 total_size) | 82 OriginInfo::OriginInfo(const std::string& origin_identifier, int64 total_size) |
| 80 : origin_identifier_(origin_identifier), total_size_(total_size) {} | 83 : origin_identifier_(origin_identifier), total_size_(total_size) { |
| 84 } |
| 81 | 85 |
| 82 DatabaseTracker::DatabaseTracker( | 86 DatabaseTracker::DatabaseTracker( |
| 83 const base::FilePath& profile_path, | 87 const base::FilePath& profile_path, |
| 84 bool is_incognito, | 88 bool is_incognito, |
| 85 quota::SpecialStoragePolicy* special_storage_policy, | 89 quota::SpecialStoragePolicy* special_storage_policy, |
| 86 quota::QuotaManagerProxy* quota_manager_proxy, | 90 quota::QuotaManagerProxy* quota_manager_proxy, |
| 87 base::MessageLoopProxy* db_tracker_thread) | 91 base::MessageLoopProxy* db_tracker_thread) |
| 88 : is_initialized_(false), | 92 : is_initialized_(false), |
| 89 is_incognito_(is_incognito), | 93 is_incognito_(is_incognito), |
| 90 force_keep_session_state_(false), | 94 force_keep_session_state_(false), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 118 *database_size = 0; | 122 *database_size = 0; |
| 119 return; | 123 return; |
| 120 } | 124 } |
| 121 | 125 |
| 122 if (quota_manager_proxy_.get()) | 126 if (quota_manager_proxy_.get()) |
| 123 quota_manager_proxy_->NotifyStorageAccessed( | 127 quota_manager_proxy_->NotifyStorageAccessed( |
| 124 quota::QuotaClient::kDatabase, | 128 quota::QuotaClient::kDatabase, |
| 125 webkit_database::GetOriginFromIdentifier(origin_identifier), | 129 webkit_database::GetOriginFromIdentifier(origin_identifier), |
| 126 quota::kStorageTypeTemporary); | 130 quota::kStorageTypeTemporary); |
| 127 | 131 |
| 128 InsertOrUpdateDatabaseDetails(origin_identifier, database_name, | 132 InsertOrUpdateDatabaseDetails( |
| 129 database_description, estimated_size); | 133 origin_identifier, database_name, database_description, estimated_size); |
| 130 if (database_connections_.AddConnection(origin_identifier, database_name)) { | 134 if (database_connections_.AddConnection(origin_identifier, database_name)) { |
| 131 *database_size = SeedOpenDatabaseInfo(origin_identifier, | 135 *database_size = SeedOpenDatabaseInfo( |
| 132 database_name, | 136 origin_identifier, database_name, database_description); |
| 133 database_description); | |
| 134 return; | 137 return; |
| 135 } | 138 } |
| 136 *database_size = UpdateOpenDatabaseInfoAndNotify(origin_identifier, | 139 *database_size = UpdateOpenDatabaseInfoAndNotify( |
| 137 database_name, | 140 origin_identifier, database_name, &database_description); |
| 138 &database_description); | |
| 139 } | 141 } |
| 140 | 142 |
| 141 void DatabaseTracker::DatabaseModified(const std::string& origin_identifier, | 143 void DatabaseTracker::DatabaseModified(const std::string& origin_identifier, |
| 142 const base::string16& database_name) { | 144 const base::string16& database_name) { |
| 143 if (!LazyInit()) | 145 if (!LazyInit()) |
| 144 return; | 146 return; |
| 145 UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name); | 147 UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name); |
| 146 } | 148 } |
| 147 | 149 |
| 148 void DatabaseTracker::DatabaseClosed(const std::string& origin_identifier, | 150 void DatabaseTracker::DatabaseClosed(const std::string& origin_identifier, |
| 149 const base::string16& database_name) { | 151 const base::string16& database_name) { |
| 150 if (database_connections_.IsEmpty()) { | 152 if (database_connections_.IsEmpty()) { |
| 151 DCHECK(!is_initialized_); | 153 DCHECK(!is_initialized_); |
| 152 return; | 154 return; |
| 153 } | 155 } |
| 154 | 156 |
| 155 // We call NotifiyStorageAccessed when a db is opened and also when | 157 // We call NotifiyStorageAccessed when a db is opened and also when |
| 156 // closed because we don't call it for read while open. | 158 // closed because we don't call it for read while open. |
| 157 if (quota_manager_proxy_.get()) | 159 if (quota_manager_proxy_.get()) |
| 158 quota_manager_proxy_->NotifyStorageAccessed( | 160 quota_manager_proxy_->NotifyStorageAccessed( |
| 159 quota::QuotaClient::kDatabase, | 161 quota::QuotaClient::kDatabase, |
| 160 webkit_database::GetOriginFromIdentifier(origin_identifier), | 162 webkit_database::GetOriginFromIdentifier(origin_identifier), |
| 161 quota::kStorageTypeTemporary); | 163 quota::kStorageTypeTemporary); |
| 162 | 164 |
| 163 UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name); | 165 UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name); |
| 164 if (database_connections_.RemoveConnection(origin_identifier, database_name)) | 166 if (database_connections_.RemoveConnection(origin_identifier, database_name)) |
| 165 DeleteDatabaseIfNeeded(origin_identifier, database_name); | 167 DeleteDatabaseIfNeeded(origin_identifier, database_name); |
| 166 } | 168 } |
| 167 | 169 |
| 168 void DatabaseTracker::HandleSqliteError( | 170 void DatabaseTracker::HandleSqliteError(const std::string& origin_identifier, |
| 169 const std::string& origin_identifier, | 171 const base::string16& database_name, |
| 170 const base::string16& database_name, | 172 int error) { |
| 171 int error) { | |
| 172 // We only handle errors that indicate corruption and we | 173 // We only handle errors that indicate corruption and we |
| 173 // do so with a heavy hand, we delete it. Any renderers/workers | 174 // do so with a heavy hand, we delete it. Any renderers/workers |
| 174 // with this database open will receive a message to close it | 175 // with this database open will receive a message to close it |
| 175 // immediately, once all have closed, the files will be deleted. | 176 // immediately, once all have closed, the files will be deleted. |
| 176 // In the interim, all attempts to open a new connection to that | 177 // In the interim, all attempts to open a new connection to that |
| 177 // database will fail. | 178 // database will fail. |
| 178 // Note: the client-side filters out all but these two errors as | 179 // Note: the client-side filters out all but these two errors as |
| 179 // a small optimization, see WebDatabaseObserverImpl::HandleSqliteError. | 180 // a small optimization, see WebDatabaseObserverImpl::HandleSqliteError. |
| 180 if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) { | 181 if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) { |
| 181 DeleteDatabase(origin_identifier, database_name, | 182 DeleteDatabase(origin_identifier, database_name, net::CompletionCallback()); |
| 182 net::CompletionCallback()); | |
| 183 } | 183 } |
| 184 } | 184 } |
| 185 | 185 |
| 186 void DatabaseTracker::CloseDatabases(const DatabaseConnections& connections) { | 186 void DatabaseTracker::CloseDatabases(const DatabaseConnections& connections) { |
| 187 if (database_connections_.IsEmpty()) { | 187 if (database_connections_.IsEmpty()) { |
| 188 DCHECK(!is_initialized_ || connections.IsEmpty()); | 188 DCHECK(!is_initialized_ || connections.IsEmpty()); |
| 189 return; | 189 return; |
| 190 } | 190 } |
| 191 | 191 |
| 192 // When being closed by this route, there's a chance that | 192 // When being closed by this route, there's a chance that |
| 193 // the tracker missed some DatabseModified calls. This method is used | 193 // the tracker missed some DatabseModified calls. This method is used |
| 194 // when a renderer crashes to cleanup its open resources. | 194 // when a renderer crashes to cleanup its open resources. |
| 195 // We need to examine what we have in connections for the | 195 // We need to examine what we have in connections for the |
| 196 // size of each open databases and notify any differences between the | 196 // size of each open databases and notify any differences between the |
| 197 // actual file sizes now. | 197 // actual file sizes now. |
| 198 std::vector<std::pair<std::string, base::string16> > open_dbs; | 198 std::vector<std::pair<std::string, base::string16> > open_dbs; |
| 199 connections.ListConnections(&open_dbs); | 199 connections.ListConnections(&open_dbs); |
| 200 for (std::vector<std::pair<std::string, base::string16> >::iterator it = | 200 for (std::vector<std::pair<std::string, base::string16> >::iterator it = |
| 201 open_dbs.begin(); it != open_dbs.end(); ++it) | 201 open_dbs.begin(); |
| 202 it != open_dbs.end(); |
| 203 ++it) |
| 202 UpdateOpenDatabaseSizeAndNotify(it->first, it->second); | 204 UpdateOpenDatabaseSizeAndNotify(it->first, it->second); |
| 203 | 205 |
| 204 std::vector<std::pair<std::string, base::string16> > closed_dbs; | 206 std::vector<std::pair<std::string, base::string16> > closed_dbs; |
| 205 database_connections_.RemoveConnections(connections, &closed_dbs); | 207 database_connections_.RemoveConnections(connections, &closed_dbs); |
| 206 for (std::vector<std::pair<std::string, base::string16> >::iterator it = | 208 for (std::vector<std::pair<std::string, base::string16> >::iterator it = |
| 207 closed_dbs.begin(); it != closed_dbs.end(); ++it) { | 209 closed_dbs.begin(); |
| 210 it != closed_dbs.end(); |
| 211 ++it) { |
| 208 DeleteDatabaseIfNeeded(it->first, it->second); | 212 DeleteDatabaseIfNeeded(it->first, it->second); |
| 209 } | 213 } |
| 210 } | 214 } |
| 211 | 215 |
| 212 void DatabaseTracker::DeleteDatabaseIfNeeded( | 216 void DatabaseTracker::DeleteDatabaseIfNeeded( |
| 213 const std::string& origin_identifier, | 217 const std::string& origin_identifier, |
| 214 const base::string16& database_name) { | 218 const base::string16& database_name) { |
| 215 DCHECK(!database_connections_.IsDatabaseOpened(origin_identifier, | 219 DCHECK(!database_connections_.IsDatabaseOpened(origin_identifier, |
| 216 database_name)); | 220 database_name)); |
| 217 if (IsDatabaseScheduledForDeletion(origin_identifier, database_name)) { | 221 if (IsDatabaseScheduledForDeletion(origin_identifier, database_name)) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 const base::string16& database_name) { | 291 const base::string16& database_name) { |
| 288 DCHECK(!origin_identifier.empty()); | 292 DCHECK(!origin_identifier.empty()); |
| 289 if (!LazyInit()) | 293 if (!LazyInit()) |
| 290 return base::FilePath(); | 294 return base::FilePath(); |
| 291 | 295 |
| 292 int64 id = databases_table_->GetDatabaseID(origin_identifier, database_name); | 296 int64 id = databases_table_->GetDatabaseID(origin_identifier, database_name); |
| 293 if (id < 0) | 297 if (id < 0) |
| 294 return base::FilePath(); | 298 return base::FilePath(); |
| 295 | 299 |
| 296 return db_dir_.Append(base::FilePath::FromUTF16Unsafe( | 300 return db_dir_.Append(base::FilePath::FromUTF16Unsafe( |
| 297 GetOriginDirectory(origin_identifier))).AppendASCII( | 301 GetOriginDirectory(origin_identifier))) |
| 298 base::Int64ToString(id)); | 302 .AppendASCII(base::Int64ToString(id)); |
| 299 } | 303 } |
| 300 | 304 |
| 301 bool DatabaseTracker::GetOriginInfo(const std::string& origin_identifier, | 305 bool DatabaseTracker::GetOriginInfo(const std::string& origin_identifier, |
| 302 OriginInfo* info) { | 306 OriginInfo* info) { |
| 303 DCHECK(info); | 307 DCHECK(info); |
| 304 CachedOriginInfo* cached_info = GetCachedOriginInfo(origin_identifier); | 308 CachedOriginInfo* cached_info = GetCachedOriginInfo(origin_identifier); |
| 305 if (!cached_info) | 309 if (!cached_info) |
| 306 return false; | 310 return false; |
| 307 *info = OriginInfo(*cached_info); | 311 *info = OriginInfo(*cached_info); |
| 308 return true; | 312 return true; |
| 309 } | 313 } |
| 310 | 314 |
| 311 bool DatabaseTracker::GetAllOriginIdentifiers( | 315 bool DatabaseTracker::GetAllOriginIdentifiers( |
| 312 std::vector<std::string>* origin_identifiers) { | 316 std::vector<std::string>* origin_identifiers) { |
| 313 DCHECK(origin_identifiers); | 317 DCHECK(origin_identifiers); |
| 314 DCHECK(origin_identifiers->empty()); | 318 DCHECK(origin_identifiers->empty()); |
| 315 if (!LazyInit()) | 319 if (!LazyInit()) |
| 316 return false; | 320 return false; |
| 317 return databases_table_->GetAllOriginIdentifiers(origin_identifiers); | 321 return databases_table_->GetAllOriginIdentifiers(origin_identifiers); |
| 318 } | 322 } |
| 319 | 323 |
| 320 bool DatabaseTracker::GetAllOriginsInfo( | 324 bool DatabaseTracker::GetAllOriginsInfo(std::vector<OriginInfo>* origins_info) { |
| 321 std::vector<OriginInfo>* origins_info) { | |
| 322 DCHECK(origins_info); | 325 DCHECK(origins_info); |
| 323 DCHECK(origins_info->empty()); | 326 DCHECK(origins_info->empty()); |
| 324 | 327 |
| 325 std::vector<std::string> origins; | 328 std::vector<std::string> origins; |
| 326 if (!GetAllOriginIdentifiers(&origins)) | 329 if (!GetAllOriginIdentifiers(&origins)) |
| 327 return false; | 330 return false; |
| 328 | 331 |
| 329 for (std::vector<std::string>::const_iterator it = origins.begin(); | 332 for (std::vector<std::string>::const_iterator it = origins.begin(); |
| 330 it != origins.end(); it++) { | 333 it != origins.end(); |
| 334 it++) { |
| 331 CachedOriginInfo* origin_info = GetCachedOriginInfo(*it); | 335 CachedOriginInfo* origin_info = GetCachedOriginInfo(*it); |
| 332 if (!origin_info) { | 336 if (!origin_info) { |
| 333 // Restore 'origins_info' to its initial state. | 337 // Restore 'origins_info' to its initial state. |
| 334 origins_info->clear(); | 338 origins_info->clear(); |
| 335 return false; | 339 return false; |
| 336 } | 340 } |
| 337 origins_info->push_back(OriginInfo(*origin_info)); | 341 origins_info->push_back(OriginInfo(*origin_info)); |
| 338 } | 342 } |
| 339 | 343 |
| 340 return true; | 344 return true; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 365 webkit_database::GetOriginFromIdentifier(origin_identifier), | 369 webkit_database::GetOriginFromIdentifier(origin_identifier), |
| 366 quota::kStorageTypeTemporary, | 370 quota::kStorageTypeTemporary, |
| 367 -db_file_size); | 371 -db_file_size); |
| 368 | 372 |
| 369 // Clean up the main database and invalidate the cached record. | 373 // Clean up the main database and invalidate the cached record. |
| 370 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); | 374 databases_table_->DeleteDatabaseDetails(origin_identifier, database_name); |
| 371 origins_info_map_.erase(origin_identifier); | 375 origins_info_map_.erase(origin_identifier); |
| 372 | 376 |
| 373 std::vector<DatabaseDetails> details; | 377 std::vector<DatabaseDetails> details; |
| 374 if (databases_table_->GetAllDatabaseDetailsForOriginIdentifier( | 378 if (databases_table_->GetAllDatabaseDetailsForOriginIdentifier( |
| 375 origin_identifier, &details) && details.empty()) { | 379 origin_identifier, &details) && |
| 380 details.empty()) { |
| 376 // Try to delete the origin in case this was the last database. | 381 // Try to delete the origin in case this was the last database. |
| 377 DeleteOrigin(origin_identifier, false); | 382 DeleteOrigin(origin_identifier, false); |
| 378 } | 383 } |
| 379 return true; | 384 return true; |
| 380 } | 385 } |
| 381 | 386 |
| 382 bool DatabaseTracker::DeleteOrigin(const std::string& origin_identifier, | 387 bool DatabaseTracker::DeleteOrigin(const std::string& origin_identifier, |
| 383 bool force) { | 388 bool force) { |
| 384 if (!LazyInit()) | 389 if (!LazyInit()) |
| 385 return false; | 390 return false; |
| 386 | 391 |
| 387 // Check if any database in this origin is opened by any renderer. | 392 // Check if any database in this origin is opened by any renderer. |
| 388 if (database_connections_.IsOriginUsed(origin_identifier) && !force) | 393 if (database_connections_.IsOriginUsed(origin_identifier) && !force) |
| 389 return false; | 394 return false; |
| 390 | 395 |
| 391 int64 deleted_size = 0; | 396 int64 deleted_size = 0; |
| 392 if (quota_manager_proxy_.get()) { | 397 if (quota_manager_proxy_.get()) { |
| 393 CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); | 398 CachedOriginInfo* origin_info = GetCachedOriginInfo(origin_identifier); |
| 394 if (origin_info) | 399 if (origin_info) |
| 395 deleted_size = origin_info->TotalSize(); | 400 deleted_size = origin_info->TotalSize(); |
| 396 } | 401 } |
| 397 | 402 |
| 398 origins_info_map_.erase(origin_identifier); | 403 origins_info_map_.erase(origin_identifier); |
| 399 base::FilePath origin_dir = db_dir_.AppendASCII(origin_identifier); | 404 base::FilePath origin_dir = db_dir_.AppendASCII(origin_identifier); |
| 400 | 405 |
| 401 // Create a temporary directory to move possibly still existing databases to, | 406 // Create a temporary directory to move possibly still existing databases to, |
| 402 // as we can't delete the origin directory on windows if it contains opened | 407 // as we can't delete the origin directory on windows if it contains opened |
| 403 // files. | 408 // files. |
| 404 base::FilePath new_origin_dir; | 409 base::FilePath new_origin_dir; |
| 405 base::CreateTemporaryDirInDir(db_dir_, | 410 base::CreateTemporaryDirInDir( |
| 406 kTemporaryDirectoryPrefix, | 411 db_dir_, kTemporaryDirectoryPrefix, &new_origin_dir); |
| 407 &new_origin_dir); | |
| 408 base::FileEnumerator databases( | 412 base::FileEnumerator databases( |
| 409 origin_dir, | 413 origin_dir, false, base::FileEnumerator::FILES); |
| 410 false, | |
| 411 base::FileEnumerator::FILES); | |
| 412 for (base::FilePath database = databases.Next(); !database.empty(); | 414 for (base::FilePath database = databases.Next(); !database.empty(); |
| 413 database = databases.Next()) { | 415 database = databases.Next()) { |
| 414 base::FilePath new_file = new_origin_dir.Append(database.BaseName()); | 416 base::FilePath new_file = new_origin_dir.Append(database.BaseName()); |
| 415 base::Move(database, new_file); | 417 base::Move(database, new_file); |
| 416 } | 418 } |
| 417 base::DeleteFile(origin_dir, true); | 419 base::DeleteFile(origin_dir, true); |
| 418 base::DeleteFile(new_origin_dir, true); // might fail on windows. | 420 base::DeleteFile(new_origin_dir, true); // might fail on windows. |
| 419 | 421 |
| 420 databases_table_->DeleteOriginIdentifier(origin_identifier); | 422 databases_table_->DeleteOriginIdentifier(origin_identifier); |
| 421 | 423 |
| 422 if (quota_manager_proxy_.get() && deleted_size) { | 424 if (quota_manager_proxy_.get() && deleted_size) { |
| 423 quota_manager_proxy_->NotifyStorageModified( | 425 quota_manager_proxy_->NotifyStorageModified( |
| 424 quota::QuotaClient::kDatabase, | 426 quota::QuotaClient::kDatabase, |
| 425 webkit_database::GetOriginFromIdentifier(origin_identifier), | 427 webkit_database::GetOriginFromIdentifier(origin_identifier), |
| 426 quota::kStorageTypeTemporary, | 428 quota::kStorageTypeTemporary, |
| 427 -deleted_size); | 429 -deleted_size); |
| 428 } | 430 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 443 | 445 |
| 444 bool DatabaseTracker::LazyInit() { | 446 bool DatabaseTracker::LazyInit() { |
| 445 if (!is_initialized_ && !shutting_down_) { | 447 if (!is_initialized_ && !shutting_down_) { |
| 446 DCHECK(!db_->is_open()); | 448 DCHECK(!db_->is_open()); |
| 447 DCHECK(!databases_table_.get()); | 449 DCHECK(!databases_table_.get()); |
| 448 DCHECK(!meta_table_.get()); | 450 DCHECK(!meta_table_.get()); |
| 449 | 451 |
| 450 // If there are left-over directories from failed deletion attempts, clean | 452 // If there are left-over directories from failed deletion attempts, clean |
| 451 // them up. | 453 // them up. |
| 452 if (base::DirectoryExists(db_dir_)) { | 454 if (base::DirectoryExists(db_dir_)) { |
| 453 base::FileEnumerator directories( | 455 base::FileEnumerator directories(db_dir_, |
| 454 db_dir_, | 456 false, |
| 455 false, | 457 base::FileEnumerator::DIRECTORIES, |
| 456 base::FileEnumerator::DIRECTORIES, | 458 kTemporaryDirectoryPattern); |
| 457 kTemporaryDirectoryPattern); | |
| 458 for (base::FilePath directory = directories.Next(); !directory.empty(); | 459 for (base::FilePath directory = directories.Next(); !directory.empty(); |
| 459 directory = directories.Next()) { | 460 directory = directories.Next()) { |
| 460 base::DeleteFile(directory, true); | 461 base::DeleteFile(directory, true); |
| 461 } | 462 } |
| 462 } | 463 } |
| 463 | 464 |
| 464 // If the tracker database exists, but it's corrupt or doesn't | 465 // If the tracker database exists, but it's corrupt or doesn't |
| 465 // have a meta table, delete the database directory. | 466 // have a meta table, delete the database directory. |
| 466 const base::FilePath kTrackerDatabaseFullPath = | 467 const base::FilePath kTrackerDatabaseFullPath = |
| 467 db_dir_.Append(base::FilePath(kTrackerDatabaseFileName)); | 468 db_dir_.Append(base::FilePath(kTrackerDatabaseFileName)); |
| 468 if (base::DirectoryExists(db_dir_) && | 469 if (base::DirectoryExists(db_dir_) && |
| 469 base::PathExists(kTrackerDatabaseFullPath) && | 470 base::PathExists(kTrackerDatabaseFullPath) && |
| 470 (!db_->Open(kTrackerDatabaseFullPath) || | 471 (!db_->Open(kTrackerDatabaseFullPath) || |
| 471 !sql::MetaTable::DoesTableExist(db_.get()))) { | 472 !sql::MetaTable::DoesTableExist(db_.get()))) { |
| 472 db_->Close(); | 473 db_->Close(); |
| 473 if (!base::DeleteFile(db_dir_, true)) | 474 if (!base::DeleteFile(db_dir_, true)) |
| 474 return false; | 475 return false; |
| 475 } | 476 } |
| 476 | 477 |
| 477 db_->set_histogram_tag("DatabaseTracker"); | 478 db_->set_histogram_tag("DatabaseTracker"); |
| 478 | 479 |
| 479 databases_table_.reset(new DatabasesTable(db_.get())); | 480 databases_table_.reset(new DatabasesTable(db_.get())); |
| 480 meta_table_.reset(new sql::MetaTable()); | 481 meta_table_.reset(new sql::MetaTable()); |
| 481 | 482 |
| 482 is_initialized_ = | 483 is_initialized_ = base::CreateDirectory(db_dir_) && |
| 483 base::CreateDirectory(db_dir_) && | 484 (db_->is_open() || |
| 484 (db_->is_open() || | 485 (is_incognito_ ? db_->OpenInMemory() |
| 485 (is_incognito_ ? db_->OpenInMemory() : | 486 : db_->Open(kTrackerDatabaseFullPath))) && |
| 486 db_->Open(kTrackerDatabaseFullPath))) && | 487 UpgradeToCurrentVersion(); |
| 487 UpgradeToCurrentVersion(); | |
| 488 if (!is_initialized_) { | 488 if (!is_initialized_) { |
| 489 databases_table_.reset(NULL); | 489 databases_table_.reset(NULL); |
| 490 meta_table_.reset(NULL); | 490 meta_table_.reset(NULL); |
| 491 db_->Close(); | 491 db_->Close(); |
| 492 } | 492 } |
| 493 } | 493 } |
| 494 return is_initialized_; | 494 return is_initialized_; |
| 495 } | 495 } |
| 496 | 496 |
| 497 bool DatabaseTracker::UpgradeToCurrentVersion() { | 497 bool DatabaseTracker::UpgradeToCurrentVersion() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 527 details.estimated_size = estimated_size; | 527 details.estimated_size = estimated_size; |
| 528 databases_table_->UpdateDatabaseDetails(details); | 528 databases_table_->UpdateDatabaseDetails(details); |
| 529 } | 529 } |
| 530 } | 530 } |
| 531 | 531 |
| 532 void DatabaseTracker::ClearAllCachedOriginInfo() { | 532 void DatabaseTracker::ClearAllCachedOriginInfo() { |
| 533 origins_info_map_.clear(); | 533 origins_info_map_.clear(); |
| 534 } | 534 } |
| 535 | 535 |
| 536 DatabaseTracker::CachedOriginInfo* DatabaseTracker::MaybeGetCachedOriginInfo( | 536 DatabaseTracker::CachedOriginInfo* DatabaseTracker::MaybeGetCachedOriginInfo( |
| 537 const std::string& origin_identifier, bool create_if_needed) { | 537 const std::string& origin_identifier, |
| 538 bool create_if_needed) { |
| 538 if (!LazyInit()) | 539 if (!LazyInit()) |
| 539 return NULL; | 540 return NULL; |
| 540 | 541 |
| 541 // Populate the cache with data for this origin if needed. | 542 // Populate the cache with data for this origin if needed. |
| 542 if (origins_info_map_.find(origin_identifier) == origins_info_map_.end()) { | 543 if (origins_info_map_.find(origin_identifier) == origins_info_map_.end()) { |
| 543 if (!create_if_needed) | 544 if (!create_if_needed) |
| 544 return NULL; | 545 return NULL; |
| 545 | 546 |
| 546 std::vector<DatabaseDetails> details; | 547 std::vector<DatabaseDetails> details; |
| 547 if (!databases_table_->GetAllDatabaseDetailsForOriginIdentifier( | 548 if (!databases_table_->GetAllDatabaseDetailsForOriginIdentifier( |
| 548 origin_identifier, &details)) { | 549 origin_identifier, &details)) { |
| 549 return NULL; | 550 return NULL; |
| 550 } | 551 } |
| 551 | 552 |
| 552 CachedOriginInfo& origin_info = origins_info_map_[origin_identifier]; | 553 CachedOriginInfo& origin_info = origins_info_map_[origin_identifier]; |
| 553 origin_info.SetOriginIdentifier(origin_identifier); | 554 origin_info.SetOriginIdentifier(origin_identifier); |
| 554 for (std::vector<DatabaseDetails>::const_iterator it = details.begin(); | 555 for (std::vector<DatabaseDetails>::const_iterator it = details.begin(); |
| 555 it != details.end(); it++) { | 556 it != details.end(); |
| 557 it++) { |
| 556 int64 db_file_size; | 558 int64 db_file_size; |
| 557 if (database_connections_.IsDatabaseOpened( | 559 if (database_connections_.IsDatabaseOpened(origin_identifier, |
| 558 origin_identifier, it->database_name)) { | 560 it->database_name)) { |
| 559 db_file_size = database_connections_.GetOpenDatabaseSize( | 561 db_file_size = database_connections_.GetOpenDatabaseSize( |
| 560 origin_identifier, it->database_name); | 562 origin_identifier, it->database_name); |
| 561 } else { | 563 } else { |
| 562 db_file_size = GetDBFileSize(origin_identifier, it->database_name); | 564 db_file_size = GetDBFileSize(origin_identifier, it->database_name); |
| 563 } | 565 } |
| 564 origin_info.SetDatabaseSize(it->database_name, db_file_size); | 566 origin_info.SetDatabaseSize(it->database_name, db_file_size); |
| 565 origin_info.SetDatabaseDescription(it->database_name, it->description); | 567 origin_info.SetDatabaseDescription(it->database_name, it->description); |
| 566 } | 568 } |
| 567 } | 569 } |
| 568 | 570 |
| 569 return &origins_info_map_[origin_identifier]; | 571 return &origins_info_map_[origin_identifier]; |
| 570 } | 572 } |
| 571 | 573 |
| 572 int64 DatabaseTracker::GetDBFileSize(const std::string& origin_identifier, | 574 int64 DatabaseTracker::GetDBFileSize(const std::string& origin_identifier, |
| 573 const base::string16& database_name) { | 575 const base::string16& database_name) { |
| 574 base::FilePath db_file_name = GetFullDBFilePath(origin_identifier, | 576 base::FilePath db_file_name = |
| 575 database_name); | 577 GetFullDBFilePath(origin_identifier, database_name); |
| 576 int64 db_file_size = 0; | 578 int64 db_file_size = 0; |
| 577 if (!base::GetFileSize(db_file_name, &db_file_size)) | 579 if (!base::GetFileSize(db_file_name, &db_file_size)) |
| 578 db_file_size = 0; | 580 db_file_size = 0; |
| 579 return db_file_size; | 581 return db_file_size; |
| 580 } | 582 } |
| 581 | 583 |
| 582 int64 DatabaseTracker::SeedOpenDatabaseInfo( | 584 int64 DatabaseTracker::SeedOpenDatabaseInfo(const std::string& origin_id, |
| 583 const std::string& origin_id, const base::string16& name, | 585 const base::string16& name, |
| 584 const base::string16& description) { | 586 const base::string16& description) { |
| 585 DCHECK(database_connections_.IsDatabaseOpened(origin_id, name)); | 587 DCHECK(database_connections_.IsDatabaseOpened(origin_id, name)); |
| 586 int64 size = GetDBFileSize(origin_id, name); | 588 int64 size = GetDBFileSize(origin_id, name); |
| 587 database_connections_.SetOpenDatabaseSize(origin_id, name, size); | 589 database_connections_.SetOpenDatabaseSize(origin_id, name, size); |
| 588 CachedOriginInfo* info = MaybeGetCachedOriginInfo(origin_id, false); | 590 CachedOriginInfo* info = MaybeGetCachedOriginInfo(origin_id, false); |
| 589 if (info) { | 591 if (info) { |
| 590 info->SetDatabaseSize(name, size); | 592 info->SetDatabaseSize(name, size); |
| 591 info->SetDatabaseDescription(name, description); | 593 info->SetDatabaseDescription(name, description); |
| 592 } | 594 } |
| 593 return size; | 595 return size; |
| 594 } | 596 } |
| 595 | 597 |
| 596 int64 DatabaseTracker::UpdateOpenDatabaseInfoAndNotify( | 598 int64 DatabaseTracker::UpdateOpenDatabaseInfoAndNotify( |
| 597 const std::string& origin_id, const base::string16& name, | 599 const std::string& origin_id, |
| 600 const base::string16& name, |
| 598 const base::string16* opt_description) { | 601 const base::string16* opt_description) { |
| 599 DCHECK(database_connections_.IsDatabaseOpened(origin_id, name)); | 602 DCHECK(database_connections_.IsDatabaseOpened(origin_id, name)); |
| 600 int64 new_size = GetDBFileSize(origin_id, name); | 603 int64 new_size = GetDBFileSize(origin_id, name); |
| 601 int64 old_size = database_connections_.GetOpenDatabaseSize(origin_id, name); | 604 int64 old_size = database_connections_.GetOpenDatabaseSize(origin_id, name); |
| 602 CachedOriginInfo* info = MaybeGetCachedOriginInfo(origin_id, false); | 605 CachedOriginInfo* info = MaybeGetCachedOriginInfo(origin_id, false); |
| 603 if (info && opt_description) | 606 if (info && opt_description) |
| 604 info->SetDatabaseDescription(name, *opt_description); | 607 info->SetDatabaseDescription(name, *opt_description); |
| 605 if (old_size != new_size) { | 608 if (old_size != new_size) { |
| 606 database_connections_.SetOpenDatabaseSize(origin_id, name, new_size); | 609 database_connections_.SetOpenDatabaseSize(origin_id, name, new_size); |
| 607 if (info) | 610 if (info) |
| 608 info->SetDatabaseSize(name, new_size); | 611 info->SetDatabaseSize(name, new_size); |
| 609 if (quota_manager_proxy_.get()) | 612 if (quota_manager_proxy_.get()) |
| 610 quota_manager_proxy_->NotifyStorageModified( | 613 quota_manager_proxy_->NotifyStorageModified( |
| 611 quota::QuotaClient::kDatabase, | 614 quota::QuotaClient::kDatabase, |
| 612 webkit_database::GetOriginFromIdentifier(origin_id), | 615 webkit_database::GetOriginFromIdentifier(origin_id), |
| 613 quota::kStorageTypeTemporary, | 616 quota::kStorageTypeTemporary, |
| 614 new_size - old_size); | 617 new_size - old_size); |
| 615 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseSizeChanged( | 618 FOR_EACH_OBSERVER( |
| 616 origin_id, name, new_size)); | 619 Observer, observers_, OnDatabaseSizeChanged(origin_id, name, new_size)); |
| 617 } | 620 } |
| 618 return new_size; | 621 return new_size; |
| 619 } | 622 } |
| 620 | 623 |
| 621 void DatabaseTracker::ScheduleDatabaseForDeletion( | 624 void DatabaseTracker::ScheduleDatabaseForDeletion( |
| 622 const std::string& origin_identifier, | 625 const std::string& origin_identifier, |
| 623 const base::string16& database_name) { | 626 const base::string16& database_name) { |
| 624 DCHECK(database_connections_.IsDatabaseOpened(origin_identifier, | 627 DCHECK( |
| 625 database_name)); | 628 database_connections_.IsDatabaseOpened(origin_identifier, database_name)); |
| 626 dbs_to_be_deleted_[origin_identifier].insert(database_name); | 629 dbs_to_be_deleted_[origin_identifier].insert(database_name); |
| 627 FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseScheduledForDeletion( | 630 FOR_EACH_OBSERVER( |
| 628 origin_identifier, database_name)); | 631 Observer, |
| 632 observers_, |
| 633 OnDatabaseScheduledForDeletion(origin_identifier, database_name)); |
| 629 } | 634 } |
| 630 | 635 |
| 631 void DatabaseTracker::ScheduleDatabasesForDeletion( | 636 void DatabaseTracker::ScheduleDatabasesForDeletion( |
| 632 const DatabaseSet& databases, | 637 const DatabaseSet& databases, |
| 633 const net::CompletionCallback& callback) { | 638 const net::CompletionCallback& callback) { |
| 634 DCHECK(!databases.empty()); | 639 DCHECK(!databases.empty()); |
| 635 | 640 |
| 636 if (!callback.is_null()) | 641 if (!callback.is_null()) |
| 637 deletion_callbacks_.push_back(std::make_pair(callback, databases)); | 642 deletion_callbacks_.push_back(std::make_pair(callback, databases)); |
| 638 for (DatabaseSet::const_iterator ori = databases.begin(); | 643 for (DatabaseSet::const_iterator ori = databases.begin(); |
| 639 ori != databases.end(); ++ori) { | 644 ori != databases.end(); |
| 645 ++ori) { |
| 640 for (std::set<base::string16>::const_iterator db = ori->second.begin(); | 646 for (std::set<base::string16>::const_iterator db = ori->second.begin(); |
| 641 db != ori->second.end(); ++db) | 647 db != ori->second.end(); |
| 648 ++db) |
| 642 ScheduleDatabaseForDeletion(ori->first, *db); | 649 ScheduleDatabaseForDeletion(ori->first, *db); |
| 643 } | 650 } |
| 644 } | 651 } |
| 645 | 652 |
| 646 int DatabaseTracker::DeleteDatabase(const std::string& origin_identifier, | 653 int DatabaseTracker::DeleteDatabase(const std::string& origin_identifier, |
| 647 const base::string16& database_name, | 654 const base::string16& database_name, |
| 648 const net::CompletionCallback& callback) { | 655 const net::CompletionCallback& callback) { |
| 649 if (!LazyInit()) | 656 if (!LazyInit()) |
| 650 return net::ERR_FAILED; | 657 return net::ERR_FAILED; |
| 651 | 658 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 670 return net::ERR_FAILED; | 677 return net::ERR_FAILED; |
| 671 | 678 |
| 672 DatabaseSet to_be_deleted; | 679 DatabaseSet to_be_deleted; |
| 673 | 680 |
| 674 std::vector<std::string> origins_identifiers; | 681 std::vector<std::string> origins_identifiers; |
| 675 if (!databases_table_->GetAllOriginIdentifiers(&origins_identifiers)) | 682 if (!databases_table_->GetAllOriginIdentifiers(&origins_identifiers)) |
| 676 return net::ERR_FAILED; | 683 return net::ERR_FAILED; |
| 677 int rv = net::OK; | 684 int rv = net::OK; |
| 678 for (std::vector<std::string>::const_iterator ori = | 685 for (std::vector<std::string>::const_iterator ori = |
| 679 origins_identifiers.begin(); | 686 origins_identifiers.begin(); |
| 680 ori != origins_identifiers.end(); ++ori) { | 687 ori != origins_identifiers.end(); |
| 688 ++ori) { |
| 681 if (special_storage_policy_.get() && | 689 if (special_storage_policy_.get() && |
| 682 special_storage_policy_->IsStorageProtected( | 690 special_storage_policy_->IsStorageProtected( |
| 683 webkit_database::GetOriginFromIdentifier(*ori))) { | 691 webkit_database::GetOriginFromIdentifier(*ori))) { |
| 684 continue; | 692 continue; |
| 685 } | 693 } |
| 686 | 694 |
| 687 std::vector<DatabaseDetails> details; | 695 std::vector<DatabaseDetails> details; |
| 688 if (!databases_table_-> | 696 if (!databases_table_->GetAllDatabaseDetailsForOriginIdentifier(*ori, |
| 689 GetAllDatabaseDetailsForOriginIdentifier(*ori, &details)) | 697 &details)) |
| 690 rv = net::ERR_FAILED; | 698 rv = net::ERR_FAILED; |
| 691 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); | 699 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); |
| 692 db != details.end(); ++db) { | 700 db != details.end(); |
| 701 ++db) { |
| 693 base::FilePath db_file = GetFullDBFilePath(*ori, db->database_name); | 702 base::FilePath db_file = GetFullDBFilePath(*ori, db->database_name); |
| 694 base::File::Info file_info; | 703 base::File::Info file_info; |
| 695 base::GetFileInfo(db_file, &file_info); | 704 base::GetFileInfo(db_file, &file_info); |
| 696 if (file_info.last_modified < cutoff) | 705 if (file_info.last_modified < cutoff) |
| 697 continue; | 706 continue; |
| 698 | 707 |
| 699 // Check if the database is opened by any renderer. | 708 // Check if the database is opened by any renderer. |
| 700 if (database_connections_.IsDatabaseOpened(*ori, db->database_name)) | 709 if (database_connections_.IsDatabaseOpened(*ori, db->database_name)) |
| 701 to_be_deleted[*ori].insert(db->database_name); | 710 to_be_deleted[*ori].insert(db->database_name); |
| 702 else | 711 else |
| 703 DeleteClosedDatabase(*ori, db->database_name); | 712 DeleteClosedDatabase(*ori, db->database_name); |
| 704 } | 713 } |
| 705 } | 714 } |
| 706 | 715 |
| 707 if (rv != net::OK) | 716 if (rv != net::OK) |
| 708 return rv; | 717 return rv; |
| 709 | 718 |
| 710 if (!to_be_deleted.empty()) { | 719 if (!to_be_deleted.empty()) { |
| 711 ScheduleDatabasesForDeletion(to_be_deleted, callback); | 720 ScheduleDatabasesForDeletion(to_be_deleted, callback); |
| 712 return net::ERR_IO_PENDING; | 721 return net::ERR_IO_PENDING; |
| 713 } | 722 } |
| 714 return net::OK; | 723 return net::OK; |
| 715 } | 724 } |
| 716 | 725 |
| 717 int DatabaseTracker::DeleteDataForOrigin( | 726 int DatabaseTracker::DeleteDataForOrigin( |
| 718 const std::string& origin, const net::CompletionCallback& callback) { | 727 const std::string& origin, |
| 728 const net::CompletionCallback& callback) { |
| 719 if (!LazyInit()) | 729 if (!LazyInit()) |
| 720 return net::ERR_FAILED; | 730 return net::ERR_FAILED; |
| 721 | 731 |
| 722 DatabaseSet to_be_deleted; | 732 DatabaseSet to_be_deleted; |
| 723 | 733 |
| 724 std::vector<DatabaseDetails> details; | 734 std::vector<DatabaseDetails> details; |
| 725 if (!databases_table_-> | 735 if (!databases_table_->GetAllDatabaseDetailsForOriginIdentifier(origin, |
| 726 GetAllDatabaseDetailsForOriginIdentifier(origin, &details)) | 736 &details)) |
| 727 return net::ERR_FAILED; | 737 return net::ERR_FAILED; |
| 728 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); | 738 for (std::vector<DatabaseDetails>::const_iterator db = details.begin(); |
| 729 db != details.end(); ++db) { | 739 db != details.end(); |
| 740 ++db) { |
| 730 // Check if the database is opened by any renderer. | 741 // Check if the database is opened by any renderer. |
| 731 if (database_connections_.IsDatabaseOpened(origin, db->database_name)) | 742 if (database_connections_.IsDatabaseOpened(origin, db->database_name)) |
| 732 to_be_deleted[origin].insert(db->database_name); | 743 to_be_deleted[origin].insert(db->database_name); |
| 733 else | 744 else |
| 734 DeleteClosedDatabase(origin, db->database_name); | 745 DeleteClosedDatabase(origin, db->database_name); |
| 735 } | 746 } |
| 736 | 747 |
| 737 if (!to_be_deleted.empty()) { | 748 if (!to_be_deleted.empty()) { |
| 738 ScheduleDatabasesForDeletion(to_be_deleted, callback); | 749 ScheduleDatabasesForDeletion(to_be_deleted, callback); |
| 739 return net::ERR_IO_PENDING; | 750 return net::ERR_IO_PENDING; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 bool DatabaseTracker::HasSavedIncognitoFileHandle( | 793 bool DatabaseTracker::HasSavedIncognitoFileHandle( |
| 783 const base::string16& vfs_file_name) const { | 794 const base::string16& vfs_file_name) const { |
| 784 return (incognito_file_handles_.find(vfs_file_name) != | 795 return (incognito_file_handles_.find(vfs_file_name) != |
| 785 incognito_file_handles_.end()); | 796 incognito_file_handles_.end()); |
| 786 } | 797 } |
| 787 | 798 |
| 788 void DatabaseTracker::DeleteIncognitoDBDirectory() { | 799 void DatabaseTracker::DeleteIncognitoDBDirectory() { |
| 789 is_initialized_ = false; | 800 is_initialized_ = false; |
| 790 | 801 |
| 791 for (FileHandlesMap::iterator it = incognito_file_handles_.begin(); | 802 for (FileHandlesMap::iterator it = incognito_file_handles_.begin(); |
| 792 it != incognito_file_handles_.end(); it++) { | 803 it != incognito_file_handles_.end(); |
| 804 it++) { |
| 793 delete it->second; | 805 delete it->second; |
| 794 } | 806 } |
| 795 | 807 |
| 796 base::FilePath incognito_db_dir = | 808 base::FilePath incognito_db_dir = |
| 797 profile_path_.Append(kIncognitoDatabaseDirectoryName); | 809 profile_path_.Append(kIncognitoDatabaseDirectoryName); |
| 798 if (base::DirectoryExists(incognito_db_dir)) | 810 if (base::DirectoryExists(incognito_db_dir)) |
| 799 base::DeleteFile(incognito_db_dir, true); | 811 base::DeleteFile(incognito_db_dir, true); |
| 800 } | 812 } |
| 801 | 813 |
| 802 void DatabaseTracker::ClearSessionOnlyOrigins() { | 814 void DatabaseTracker::ClearSessionOnlyOrigins() { |
| 803 bool has_session_only_databases = | 815 bool has_session_only_databases = |
| 804 special_storage_policy_.get() && | 816 special_storage_policy_.get() && |
| 805 special_storage_policy_->HasSessionOnlyOrigins(); | 817 special_storage_policy_->HasSessionOnlyOrigins(); |
| 806 | 818 |
| 807 // Clearing only session-only databases, and there are none. | 819 // Clearing only session-only databases, and there are none. |
| 808 if (!has_session_only_databases) | 820 if (!has_session_only_databases) |
| 809 return; | 821 return; |
| 810 | 822 |
| 811 if (!LazyInit()) | 823 if (!LazyInit()) |
| 812 return; | 824 return; |
| 813 | 825 |
| 814 std::vector<std::string> origin_identifiers; | 826 std::vector<std::string> origin_identifiers; |
| 815 GetAllOriginIdentifiers(&origin_identifiers); | 827 GetAllOriginIdentifiers(&origin_identifiers); |
| 816 | 828 |
| 817 for (std::vector<std::string>::iterator origin = | 829 for (std::vector<std::string>::iterator origin = origin_identifiers.begin(); |
| 818 origin_identifiers.begin(); | 830 origin != origin_identifiers.end(); |
| 819 origin != origin_identifiers.end(); ++origin) { | 831 ++origin) { |
| 820 GURL origin_url = webkit_database::GetOriginFromIdentifier(*origin); | 832 GURL origin_url = webkit_database::GetOriginFromIdentifier(*origin); |
| 821 if (!special_storage_policy_->IsStorageSessionOnly(origin_url)) | 833 if (!special_storage_policy_->IsStorageSessionOnly(origin_url)) |
| 822 continue; | 834 continue; |
| 823 if (special_storage_policy_->IsStorageProtected(origin_url)) | 835 if (special_storage_policy_->IsStorageProtected(origin_url)) |
| 824 continue; | 836 continue; |
| 825 webkit_database::OriginInfo origin_info; | 837 webkit_database::OriginInfo origin_info; |
| 826 std::vector<base::string16> databases; | 838 std::vector<base::string16> databases; |
| 827 GetOriginInfo(*origin, &origin_info); | 839 GetOriginInfo(*origin, &origin_info); |
| 828 origin_info.GetAllDatabaseNames(&databases); | 840 origin_info.GetAllDatabaseNames(&databases); |
| 829 | 841 |
| 830 for (std::vector<base::string16>::iterator database = databases.begin(); | 842 for (std::vector<base::string16>::iterator database = databases.begin(); |
| 831 database != databases.end(); ++database) { | 843 database != databases.end(); |
| 832 base::File file(GetFullDBFilePath(*origin, *database), | 844 ++database) { |
| 833 base::File::FLAG_OPEN_ALWAYS | | 845 base::File file( |
| 834 base::File::FLAG_SHARE_DELETE | | 846 GetFullDBFilePath(*origin, *database), |
| 835 base::File::FLAG_DELETE_ON_CLOSE | | 847 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_SHARE_DELETE | |
| 836 base::File::FLAG_READ); | 848 base::File::FLAG_DELETE_ON_CLOSE | base::File::FLAG_READ); |
| 837 } | 849 } |
| 838 DeleteOrigin(*origin, true); | 850 DeleteOrigin(*origin, true); |
| 839 } | 851 } |
| 840 } | 852 } |
| 841 | 853 |
| 842 | |
| 843 void DatabaseTracker::Shutdown() { | 854 void DatabaseTracker::Shutdown() { |
| 844 DCHECK(db_tracker_thread_.get()); | 855 DCHECK(db_tracker_thread_.get()); |
| 845 DCHECK(db_tracker_thread_->BelongsToCurrentThread()); | 856 DCHECK(db_tracker_thread_->BelongsToCurrentThread()); |
| 846 if (shutting_down_) { | 857 if (shutting_down_) { |
| 847 NOTREACHED(); | 858 NOTREACHED(); |
| 848 return; | 859 return; |
| 849 } | 860 } |
| 850 shutting_down_ = true; | 861 shutting_down_ = true; |
| 851 if (is_incognito_) | 862 if (is_incognito_) |
| 852 DeleteIncognitoDBDirectory(); | 863 DeleteIncognitoDBDirectory(); |
| 853 else if (!force_keep_session_state_) | 864 else if (!force_keep_session_state_) |
| 854 ClearSessionOnlyOrigins(); | 865 ClearSessionOnlyOrigins(); |
| 855 CloseTrackerDatabaseAndClearCaches(); | 866 CloseTrackerDatabaseAndClearCaches(); |
| 856 } | 867 } |
| 857 | 868 |
| 858 void DatabaseTracker::SetForceKeepSessionState() { | 869 void DatabaseTracker::SetForceKeepSessionState() { |
| 859 DCHECK(db_tracker_thread_.get()); | 870 DCHECK(db_tracker_thread_.get()); |
| 860 if (!db_tracker_thread_->BelongsToCurrentThread()) { | 871 if (!db_tracker_thread_->BelongsToCurrentThread()) { |
| 861 db_tracker_thread_->PostTask( | 872 db_tracker_thread_->PostTask( |
| 862 FROM_HERE, | 873 FROM_HERE, |
| 863 base::Bind(&DatabaseTracker::SetForceKeepSessionState, this)); | 874 base::Bind(&DatabaseTracker::SetForceKeepSessionState, this)); |
| 864 return; | 875 return; |
| 865 } | 876 } |
| 866 force_keep_session_state_ = true; | 877 force_keep_session_state_ = true; |
| 867 } | 878 } |
| 868 | 879 |
| 869 } // namespace webkit_database | 880 } // namespace webkit_database |
| OLD | NEW |