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 "content/browser/in_process_webkit/indexed_db_context_impl.h" | 5 #include "content/browser/in_process_webkit/indexed_db_context_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 base::PlatformFileInfo file_info; | 137 base::PlatformFileInfo file_info; |
138 if (!file_util::GetFileInfo(idb_directory, &file_info)) | 138 if (!file_util::GetFileInfo(idb_directory, &file_info)) |
139 return base::Time(); | 139 return base::Time(); |
140 return file_info.last_modified; | 140 return file_info.last_modified; |
141 } | 141 } |
142 | 142 |
143 void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) { | 143 void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) { |
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
145 if (data_path_.empty() || !IsInOriginSet(origin_url)) | 145 if (data_path_.empty() || !IsInOriginSet(origin_url)) |
146 return; | 146 return; |
147 // TODO(michaeln): When asked to delete an origin with open connections, | 147 |
148 // forcibly close those connections then delete. | 148 if (connections_.find(origin_url) != connections_.end()) { |
149 if (connection_count_.find(origin_url) == connection_count_.end()) { | 149 ConnectionSet& connections = connections_[origin_url]; |
150 string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url); | 150 ConnectionSet::iterator it = connections.begin(); |
151 FilePath idb_directory = GetIndexedDBFilePath(origin_id); | 151 while (it != connections.end()) { |
152 EnsureDiskUsageCacheInitialized(origin_url); | 152 // Remove before closing so callbacks don't double-erase |
153 bool deleted = file_util::Delete(idb_directory, true /*recursive*/); | 153 WebKit::WebIDBDatabase* db = *it; |
154 QueryDiskAndUpdateQuotaUsage(origin_url); | 154 connections.erase(it++); |
155 if (deleted) { | 155 db->forceClose(); |
156 RemoveFromOriginSet(origin_url); | |
157 origin_size_map_.erase(origin_url); | |
158 space_available_map_.erase(origin_url); | |
159 } | 156 } |
| 157 DCHECK(connections_[origin_url].size() == 0); |
| 158 connections_.erase(origin_url); |
| 159 } |
| 160 |
| 161 string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url); |
| 162 FilePath idb_directory = GetIndexedDBFilePath(origin_id); |
| 163 EnsureDiskUsageCacheInitialized(origin_url); |
| 164 const bool recursive = true; |
| 165 bool deleted = file_util::Delete(idb_directory, recursive); |
| 166 |
| 167 QueryDiskAndUpdateQuotaUsage(origin_url); |
| 168 if (deleted) { |
| 169 RemoveFromOriginSet(origin_url); |
| 170 origin_size_map_.erase(origin_url); |
| 171 space_available_map_.erase(origin_url); |
160 } | 172 } |
161 } | 173 } |
162 | 174 |
163 FilePath IndexedDBContextImpl::GetFilePathForTesting( | 175 FilePath IndexedDBContextImpl::GetFilePathForTesting( |
164 const string16& origin_id) const { | 176 const string16& origin_id) const { |
165 return GetIndexedDBFilePath(origin_id); | 177 return GetIndexedDBFilePath(origin_id); |
166 } | 178 } |
167 | 179 |
168 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url) { | 180 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, |
| 181 WebIDBDatabase* connection) { |
| 182 DCHECK(connections_[origin_url].count(connection) == 0); |
169 if (quota_manager_proxy()) { | 183 if (quota_manager_proxy()) { |
170 quota_manager_proxy()->NotifyStorageAccessed( | 184 quota_manager_proxy()->NotifyStorageAccessed( |
171 quota::QuotaClient::kIndexedDatabase, origin_url, | 185 quota::QuotaClient::kIndexedDatabase, origin_url, |
172 quota::kStorageTypeTemporary); | 186 quota::kStorageTypeTemporary); |
173 } | 187 } |
174 connection_count_[origin_url]++; | 188 connections_[origin_url].insert(connection); |
175 if (AddToOriginSet(origin_url)) { | 189 if (AddToOriginSet(origin_url)) { |
176 // A newly created db, notify the quota system. | 190 // A newly created db, notify the quota system. |
177 QueryDiskAndUpdateQuotaUsage(origin_url); | 191 QueryDiskAndUpdateQuotaUsage(origin_url); |
178 } else { | 192 } else { |
179 EnsureDiskUsageCacheInitialized(origin_url); | 193 EnsureDiskUsageCacheInitialized(origin_url); |
180 } | 194 } |
181 QueryAvailableQuota(origin_url); | 195 QueryAvailableQuota(origin_url); |
182 } | 196 } |
183 | 197 |
184 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url) { | 198 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, |
185 DCHECK(connection_count_[origin_url] > 0); | 199 WebIDBDatabase* connection) { |
| 200 // May not be in the map if connection was forced to close |
| 201 if (connections_.find(origin_url) == connections_.end() || |
| 202 connections_[origin_url].count(connection) != 1) |
| 203 return; |
186 if (quota_manager_proxy()) { | 204 if (quota_manager_proxy()) { |
187 quota_manager_proxy()->NotifyStorageAccessed( | 205 quota_manager_proxy()->NotifyStorageAccessed( |
188 quota::QuotaClient::kIndexedDatabase, origin_url, | 206 quota::QuotaClient::kIndexedDatabase, origin_url, |
189 quota::kStorageTypeTemporary); | 207 quota::kStorageTypeTemporary); |
190 } | 208 } |
191 connection_count_[origin_url]--; | 209 connections_[origin_url].erase(connection); |
192 if (connection_count_[origin_url] == 0) { | 210 if (connections_[origin_url].size() == 0) { |
193 QueryDiskAndUpdateQuotaUsage(origin_url); | 211 QueryDiskAndUpdateQuotaUsage(origin_url); |
194 connection_count_.erase(origin_url); | 212 connections_.erase(origin_url); |
195 } | 213 } |
196 } | 214 } |
197 | 215 |
198 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { | 216 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { |
199 DCHECK(connection_count_[origin_url] > 0); | 217 DCHECK(connections_.find(origin_url) != connections_.end() && |
| 218 connections_[origin_url].size() > 0); |
200 QueryDiskAndUpdateQuotaUsage(origin_url); | 219 QueryDiskAndUpdateQuotaUsage(origin_url); |
201 QueryAvailableQuota(origin_url); | 220 QueryAvailableQuota(origin_url); |
202 } | 221 } |
203 | 222 |
204 bool IndexedDBContextImpl::WouldBeOverQuota(const GURL& origin_url, | 223 bool IndexedDBContextImpl::WouldBeOverQuota(const GURL& origin_url, |
205 int64 additional_bytes) { | 224 int64 additional_bytes) { |
206 if (space_available_map_.find(origin_url) == space_available_map_.end()) { | 225 if (space_available_map_.find(origin_url) == space_available_map_.end()) { |
207 // We haven't heard back from the QuotaManager yet, just let it through. | 226 // We haven't heard back from the QuotaManager yet, just let it through. |
208 return false; | 227 return false; |
209 } | 228 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 336 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); | 337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); |
319 if (quota_manager_proxy()) | 338 if (quota_manager_proxy()) |
320 BrowserThread::PostTask( | 339 BrowserThread::PostTask( |
321 BrowserThread::IO, FROM_HERE, | 340 BrowserThread::IO, FROM_HERE, |
322 base::Bind(&IndexedDBContextImpl::QueryAvailableQuota, this, | 341 base::Bind(&IndexedDBContextImpl::QueryAvailableQuota, this, |
323 origin_url)); | 342 origin_url)); |
324 return; | 343 return; |
325 } | 344 } |
326 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
327 if (!quota_manager_proxy()->quota_manager()) | 346 if (!quota_manager_proxy() || !quota_manager_proxy()->quota_manager()) |
328 return; | 347 return; |
329 quota_manager_proxy()->quota_manager()->GetUsageAndQuota( | 348 quota_manager_proxy()->quota_manager()->GetUsageAndQuota( |
330 origin_url, | 349 origin_url, |
331 quota::kStorageTypeTemporary, | 350 quota::kStorageTypeTemporary, |
332 base::Bind(&IndexedDBContextImpl::GotUsageAndQuota, this, origin_url)); | 351 base::Bind(&IndexedDBContextImpl::GotUsageAndQuota, this, origin_url)); |
333 } | 352 } |
334 | 353 |
335 std::set<GURL>* IndexedDBContextImpl::GetOriginSet() { | 354 std::set<GURL>* IndexedDBContextImpl::GetOriginSet() { |
336 if (!origin_set_.get()) { | 355 if (!origin_set_.get()) { |
337 origin_set_.reset(new std::set<GURL>); | 356 origin_set_.reset(new std::set<GURL>); |
338 std::vector<GURL> origins; | 357 std::vector<GURL> origins; |
339 GetAllOriginsAndPaths(data_path_, &origins, NULL); | 358 GetAllOriginsAndPaths(data_path_, &origins, NULL); |
340 for (std::vector<GURL>::const_iterator iter = origins.begin(); | 359 for (std::vector<GURL>::const_iterator iter = origins.begin(); |
341 iter != origins.end(); ++iter) { | 360 iter != origins.end(); ++iter) { |
342 origin_set_->insert(*iter); | 361 origin_set_->insert(*iter); |
343 } | 362 } |
344 } | 363 } |
345 return origin_set_.get(); | 364 return origin_set_.get(); |
346 } | 365 } |
347 | 366 |
348 void IndexedDBContextImpl::ResetCaches() { | 367 void IndexedDBContextImpl::ResetCaches() { |
349 origin_set_.reset(); | 368 origin_set_.reset(); |
350 origin_size_map_.clear(); | 369 origin_size_map_.clear(); |
351 space_available_map_.clear(); | 370 space_available_map_.clear(); |
352 } | 371 } |
OLD | NEW |