15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_context_impl.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include <algorithm> 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <utility> 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/metrics/histogram.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/sequenced_task_runner.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/threading/thread_restrictions.h" 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/time/time.h" 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/values.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/browser_main_loop.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/browser/indexed_db/indexed_db_connection.h" 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/browser/indexed_db/indexed_db_database.h" 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_dispatcher_host.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_factory_impl.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/indexed_db/indexed_db_quota_client.h" 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/indexed_db/indexed_db_tracing.h" 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/browser/indexed_db/indexed_db_transaction.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/indexed_db_info.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/database/database_util.h" 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h" 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/special_storage_policy.h" 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/database/database_identifier.h" 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ui/base/text/bytes_formatting.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing base::DictionaryValue; 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochusing base::ListValue; 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::DatabaseUtil; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType IndexedDBContextImpl::kIndexedDBDirectory[] = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_PATH_LITERAL("IndexedDB"); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static const base::FilePath::CharType kIndexedDBExtension[] = 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FILE_PATH_LITERAL(".indexeddb"); 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static const base::FilePath::CharType kLevelDBExtension[] = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_PATH_LITERAL(".leveldb"); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This may be called after the IndexedDBContext is destroyed. 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GetAllOriginsAndPaths(const base::FilePath& indexeddb_path, 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<GURL>* origins, 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<base::FilePath>* file_paths) { 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK that this is running on an IndexedDB thread, 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // if a global handle to it is ever available. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (indexeddb_path.empty()) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator file_enumerator( 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) indexeddb_path, false, base::FileEnumerator::DIRECTORIES); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_path = file_enumerator.Next()) { 677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (file_path.Extension() == kLevelDBExtension && 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) file_path.RemoveExtension().Extension() == kIndexedDBExtension) { 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string origin_id = file_path.BaseName().RemoveExtension() 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) .RemoveExtension().MaybeAsASCII(); 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) origins->push_back(storage::GetOriginFromIdentifier(origin_id)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_paths) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_paths->push_back(file_path); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This will be called after the IndexedDBContext is destroyed. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ClearSessionOnlyOrigins( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& indexeddb_path, 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy) { 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jsbell): DCHECK that this is running on an IndexedDB thread, 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // if a global handle to it is ever available. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> origins; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> file_paths; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAllOriginsAndPaths(indexeddb_path, &origins, &file_paths); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(origins.size(), file_paths.size()); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath>::const_iterator file_path_iter = 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_paths.begin(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<GURL>::const_iterator iter = origins.begin(); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iter != origins.end(); 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++iter, ++file_path_iter) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!special_storage_policy->IsStorageSessionOnly(*iter)) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (special_storage_policy->IsStorageProtected(*iter)) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(*file_path_iter, true); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IndexedDBContextImpl::IndexedDBContextImpl( 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& data_path, 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::SpecialStoragePolicy* special_storage_policy, 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::QuotaManagerProxy* quota_manager_proxy, 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::SequencedTaskRunner* task_runner) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : force_keep_session_state_(false), 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) special_storage_policy_(special_storage_policy), 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch quota_manager_proxy_(quota_manager_proxy), 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch task_runner_(task_runner) { 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IDB_TRACE("init"); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data_path.empty()) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_path_ = data_path.Append(kIndexedDBDirectory); 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (quota_manager_proxy) { 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch quota_manager_proxy->RegisterClient(new IndexedDBQuotaClient(this)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochIndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() { 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!factory_.get()) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prime our cache of origins with existing databases so we can 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detect when dbs are newly created. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetOriginSet(); 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) factory_ = new IndexedDBFactoryImpl(this); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return factory_.get(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<GURL> IndexedDBContextImpl::GetAllOrigins() { 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> origins; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL>* origins_set = GetOriginSet(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<GURL>::const_iterator iter = origins_set->begin(); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iter != origins_set->end(); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++iter) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origins.push_back(*iter); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return origins; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector<IndexedDBInfo> IndexedDBContextImpl::GetAllOriginsInfo() { 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<GURL> origins = GetAllOrigins(); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<IndexedDBInfo> result; 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<GURL>::const_iterator iter = origins.begin(); 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iter != origins.end(); 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++iter) { 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& origin_url = *iter; 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath idb_directory = GetFilePath(origin_url); 153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch size_t connection_count = GetConnectionCount(origin_url); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.push_back(IndexedDBInfo(origin_url, 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetOriginDiskUsage(origin_url), 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetOriginLastModified(origin_url), 157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch idb_directory, 158ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch connection_count)); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return result; 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic bool HostNameComparator(const GURL& i, const GURL& j) { 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return i.host() < j.host(); 165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() { 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 169ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<GURL> origins = GetAllOrigins(); 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::sort(origins.begin(), origins.end(), HostNameComparator); 172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> list(new base::ListValue()); 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (std::vector<GURL>::const_iterator iter = origins.begin(); 175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch iter != origins.end(); 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ++iter) { 177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GURL& origin_url = *iter; 178ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> info(new base::DictionaryValue()); 180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch info->SetString("url", origin_url.spec()); 181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch info->SetString("size", ui::FormatBytes(GetOriginDiskUsage(origin_url))); 182ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch info->SetDouble("last_modified", 183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GetOriginLastModified(origin_url).ToJsTime()); 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_incognito()) 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch info->SetString("path", GetFilePath(origin_url).value()); 186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch info->SetDouble("connection_count", GetConnectionCount(origin_url)); 187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // This ends up being O(n^2) since we iterate over all open databases 189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // to extract just those in the origin, and we're iterating over all 190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // origins in the outer loop. 191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (factory_.get()) { 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::pair<IndexedDBFactory::OriginDBMapIterator, 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IndexedDBFactory::OriginDBMapIterator> range = 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) factory_->GetOpenDatabasesForOrigin(origin_url); 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(jsbell): Sort by name? 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> database_list(new base::ListValue()); 198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (IndexedDBFactory::OriginDBMapIterator it = range.first; 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != range.second; 201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ++it) { 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const IndexedDBDatabase* db = it->second; 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> db_info(new base::DictionaryValue()); 204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->SetString("name", db->name()); 206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->SetDouble("pending_opens", db->PendingOpenCount()); 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->SetDouble("pending_upgrades", db->PendingUpgradeCount()); 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->SetDouble("running_upgrades", db->RunningUpgradeCount()); 209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->SetDouble("pending_deletes", db->PendingDeleteCount()); 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->SetDouble("connection_count", 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db->ConnectionCount() - db->PendingUpgradeCount() - 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db->RunningUpgradeCount()); 213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> transaction_list(new base::ListValue()); 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<const IndexedDBTransaction*> transactions = 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db->transaction_coordinator().GetTransactions(); 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (std::vector<const IndexedDBTransaction*>::iterator trans_it = 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch transactions.begin(); 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch trans_it != transactions.end(); 220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ++trans_it) { 221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const IndexedDBTransaction* transaction = *trans_it; 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> transaction_info( 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::DictionaryValue()); 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const char* kModes[] = { "readonly", "readwrite", "versionchange" }; 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch transaction_info->SetString("mode", kModes[transaction->mode()]); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (transaction->state()) { 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case IndexedDBTransaction::CREATED: 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetString("status", "blocked"); 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case IndexedDBTransaction::STARTED: 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (transaction->diagnostics().tasks_scheduled > 0) 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetString("status", "running"); 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetString("status", "started"); 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case IndexedDBTransaction::COMMITTING: 23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) transaction_info->SetString("status", "committing"); 23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) break; 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case IndexedDBTransaction::FINISHED: 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) transaction_info->SetString("status", "finished"); 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetDouble( 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "pid", 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) IndexedDBDispatcherHost::TransactionIdToProcessId( 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction->id())); 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetDouble( 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "tid", 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) IndexedDBDispatcherHost::TransactionIdToRendererTransactionId( 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction->id())); 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetDouble( 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "age", 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (base::Time::Now() - transaction->diagnostics().creation_time) 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) .InMillisecondsF()); 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) transaction_info->SetDouble( 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "runtime", 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (base::Time::Now() - transaction->diagnostics().start_time) 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) .InMillisecondsF()); 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) transaction_info->SetDouble( 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "tasks_scheduled", transaction->diagnostics().tasks_scheduled); 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) transaction_info->SetDouble( 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "tasks_completed", transaction->diagnostics().tasks_completed); 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> scope(new base::ListValue()); 267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (std::set<int64>::const_iterator scope_it = 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch transaction->scope().begin(); 269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scope_it != transaction->scope().end(); 270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ++scope_it) { 271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IndexedDBDatabaseMetadata::ObjectStoreMap::const_iterator it = 272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db->metadata().object_stores.find(*scope_it); 273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (it != db->metadata().object_stores.end()) 274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scope->AppendString(it->second.name); 275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch transaction_info->Set("scope", scope.release()); 278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch transaction_list->Append(transaction_info.release()); 279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch db_info->Set("transactions", transaction_list.release()); 281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch database_list->Append(db_info.release()); 283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch info->Set("databases", database_list.release()); 285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch list->Append(info.release()); 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return list.release(); 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) { 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_path_.empty() || !IsInOriginSet(origin_url)) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureDiskUsageCacheInitialized(origin_url); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return origin_size_map_[origin_url]; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time IndexedDBContextImpl::GetOriginLastModified(const GURL& origin_url) { 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_path_.empty() || !IsInOriginSet(origin_url)) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Time(); 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath idb_directory = GetFilePath(origin_url); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info file_info; 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!base::GetFileInfo(idb_directory, &file_info)) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Time(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_info.last_modified; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) { 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ForceClose(origin_url, FORCE_CLOSE_DELETE_ORIGIN); 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (data_path_.empty() || !IsInOriginSet(origin_url)) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath idb_directory = GetFilePath(origin_url); 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EnsureDiskUsageCacheInitialized(origin_url); 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status s = LevelDBDatabase::Destroy(idb_directory); 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!s.ok()) { 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Failed to delete LevelDB database: " 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << idb_directory.AsUTF8Unsafe(); 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // LevelDB does not delete empty directories; work around this. 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(jsbell): Remove when upstream bug is fixed. 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // https://code.google.com/p/leveldb/issues/detail?id=209 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const bool kNonRecursive = false; 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::DeleteFile(idb_directory, kNonRecursive); 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QueryDiskAndUpdateQuotaUsage(origin_url); 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (s.ok()) { 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RemoveFromOriginSet(origin_url); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) origin_size_map_.erase(origin_url); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) space_available_map_.erase(origin_url); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void IndexedDBContextImpl::ForceClose(const GURL origin_url, 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ForceCloseReason reason) { 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Context.ForceCloseReason", 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reason, 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FORCE_CLOSE_REASON_MAX); 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_path_.empty() || !IsInOriginSet(origin_url)) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (factory_.get()) 350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) factory_->ForceClose(origin_url); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0UL, GetConnectionCount(origin_url)); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochsize_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) { 355ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (data_path_.empty() || !IsInOriginSet(origin_url)) 357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return 0; 358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!factory_.get()) 360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return 0; 361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return factory_->GetConnectionCount(origin_url); 363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const { 36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string origin_id = storage::GetIdentifierFromOrigin(origin_url); 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return GetIndexedDBFilePath(origin_id); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath IndexedDBContextImpl::GetFilePathForTesting( 3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& origin_id) const { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetIndexedDBFilePath(origin_id); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IndexedDBContextImpl::SetTaskRunnerForTesting( 376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::SequencedTaskRunner* task_runner) { 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!task_runner_.get()); 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch task_runner_ = task_runner; 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, 382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection) { 383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quota_manager_proxy()) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_manager_proxy()->NotifyStorageAccessed( 38603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::QuotaClient::kIndexedDatabase, 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) origin_url, 38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::kStorageTypeTemporary); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AddToOriginSet(origin_url)) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A newly created db, notify the quota system. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryDiskAndUpdateQuotaUsage(origin_url); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureDiskUsageCacheInitialized(origin_url); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryAvailableQuota(origin_url); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, 400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IndexedDBConnection* connection) { 401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quota_manager_proxy()) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_manager_proxy()->NotifyStorageAccessed( 40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::QuotaClient::kIndexedDatabase, 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) origin_url, 40603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::kStorageTypeTemporary); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (factory_.get() && factory_->GetConnectionCount(origin_url) == 0) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryDiskAndUpdateQuotaUsage(origin_url); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!factory_.get() || factory_->GetConnectionCount(origin_url) > 0); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QueryDiskAndUpdateQuotaUsage(origin_url); 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QueryAvailableQuota(origin_url); 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) { 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddToOriginSet(origin_url); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryDiskAndUpdateQuotaUsage(origin_url); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryAvailableQuota(origin_url); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IndexedDBContextImpl::WouldBeOverQuota(const GURL& origin_url, 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 additional_bytes) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (space_available_map_.find(origin_url) == space_available_map_.end()) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We haven't heard back from the QuotaManager yet, just let it through. 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool over_quota = additional_bytes > space_available_map_[origin_url]; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return over_quota; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IndexedDBContextImpl::IsOverQuota(const GURL& origin_url) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kOneAdditionalByte = 1; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WouldBeOverQuota(origin_url, kOneAdditionalByte); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::QuotaManagerProxy* IndexedDBContextImpl::quota_manager_proxy() { 4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return quota_manager_proxy_.get(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IndexedDBContextImpl::~IndexedDBContextImpl() { 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (factory_.get()) { 4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) TaskRunner()->PostTask( 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FROM_HERE, base::Bind(&IndexedDBFactory::ContextDestroyed, factory_)); 447ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch factory_ = NULL; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_path_.empty()) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (force_keep_session_state_) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_session_only_databases = 4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci special_storage_policy_.get() && 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) special_storage_policy_->HasSessionOnlyOrigins(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Clearing only session-only databases, and there are none. 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_session_only_databases) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TaskRunner()->PostTask( 465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FROM_HERE, 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind( 467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &ClearSessionOnlyOrigins, data_path_, special_storage_policy_)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath IndexedDBContextImpl::GetIndexedDBFilePath( 4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& origin_id) const { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!data_path_.empty()); 473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return data_path_.AppendASCII(origin_id).AddExtension(kIndexedDBExtension) 474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch .AddExtension(kLevelDBExtension); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 IndexedDBContextImpl::ReadUsageFromDisk(const GURL& origin_url) const { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_path_.empty()) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::FilePath file_path = GetFilePath(origin_url); 481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return base::ComputeDirectorySize(file_path); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::EnsureDiskUsageCacheInitialized( 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin_url) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origin_size_map_.find(origin_url) == origin_size_map_.end()) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_size_map_[origin_url] = ReadUsageFromDisk(origin_url); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::QueryDiskAndUpdateQuotaUsage( 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin_url) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 former_disk_usage = origin_size_map_[origin_url]; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current_disk_usage = ReadUsageFromDisk(origin_url); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 difference = current_disk_usage - former_disk_usage; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (difference) { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_size_map_[origin_url] = current_disk_usage; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // quota_manager_proxy() is NULL in unit tests. 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (quota_manager_proxy()) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_manager_proxy()->NotifyStorageModified( 50003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::QuotaClient::kIndexedDatabase, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url, 50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::kStorageTypeTemporary, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) difference); 504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::GotUsageAndQuota(const GURL& origin_url, 50903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::QuotaStatusCode status, 510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 usage, 511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 quota) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 51303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(status == storage::kQuotaStatusOk || 51403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) status == storage::kQuotaErrorAbort) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "status was " << status; 51603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (status == storage::kQuotaErrorAbort) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We seem to no longer care to wait around for the answer. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TaskRunner()->PostTask(FROM_HERE, 521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&IndexedDBContextImpl::GotUpdatedQuota, 522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this, 523eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch origin_url, 524eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch usage, 525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch quota)); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void IndexedDBContextImpl::GotUpdatedQuota(const GURL& origin_url, 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64 usage, 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 quota) { 531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) space_available_map_[origin_url] = quota - usage; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::QueryAvailableQuota(const GURL& origin_url) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); 538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (quota_manager_proxy()) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::IO, 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FROM_HERE, 542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind( 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &IndexedDBContextImpl::QueryAvailableQuota, this, origin_url)); 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!quota_manager_proxy() || !quota_manager_proxy()->quota_manager()) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_manager_proxy()->quota_manager()->GetUsageAndQuota( 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url, 55203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::kStorageTypeTemporary, 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&IndexedDBContextImpl::GotUsageAndQuota, this, origin_url)); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::set<GURL>* IndexedDBContextImpl::GetOriginSet() { 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!origin_set_) { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_set_.reset(new std::set<GURL>); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> origins; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAllOriginsAndPaths(data_path_, &origins, NULL); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<GURL>::const_iterator iter = origins.begin(); 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) iter != origins.end(); 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ++iter) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_set_->insert(*iter); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return origin_set_.get(); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IndexedDBContextImpl::ResetCaches() { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_set_.reset(); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_size_map_.clear(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) space_available_map_.clear(); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::SequencedTaskRunner* IndexedDBContextImpl::TaskRunner() const { 5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return task_runner_.get(); 578eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 581