summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjsbell@chromium.org <jsbell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-22 17:57:43 +0000
committerjsbell@chromium.org <jsbell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-22 17:57:43 +0000
commit8df07d2a28b8de7a857a9e1ad8df36a6026939a8 (patch)
treef4ad471887d63c5f1d7049b44da9a8807878af1a /content
parent9550261f14a4d23cbaf01fbb2a38b6fdcf1fbe82 (diff)
downloadchromium_src-8df07d2a28b8de7a857a9e1ad8df36a6026939a8.zip
chromium_src-8df07d2a28b8de7a857a9e1ad8df36a6026939a8.tar.gz
chromium_src-8df07d2a28b8de7a857a9e1ad8df36a6026939a8.tar.bz2
Add connection/transaction diagnostics to chrome://indexeddb-internals
R=alecflett@chromium.org BUG=261651 Review URL: https://chromiumcodereview.appspot.com/19637007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212912 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.cc112
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.h4
-rw-r--r--content/browser/indexed_db/indexed_db_database.cc27
-rw-r--r--content/browser/indexed_db/indexed_db_database.h32
-rw-r--r--content/browser/indexed_db/indexed_db_database_unittest.cc26
-rw-r--r--content/browser/indexed_db/indexed_db_factory.cc27
-rw-r--r--content/browser/indexed_db/indexed_db_factory.h13
-rw-r--r--content/browser/indexed_db/indexed_db_internals_ui.cc30
-rw-r--r--content/browser/indexed_db/indexed_db_internals_ui.h2
-rw-r--r--content/browser/indexed_db/indexed_db_transaction.h1
-rw-r--r--content/browser/indexed_db/indexed_db_transaction_coordinator.cc29
-rw-r--r--content/browser/indexed_db/indexed_db_transaction_coordinator.h9
-rw-r--r--content/browser/resources/indexed_db/indexeddb_internals.css37
-rw-r--r--content/browser/resources/indexed_db/indexeddb_internals.html51
14 files changed, 326 insertions, 74 deletions
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 2c3b21f..38decc2 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
@@ -13,18 +15,24 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
+#include "base/values.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
+#include "content/browser/indexed_db/indexed_db_database.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
#include "content/browser/indexed_db/indexed_db_quota_client.h"
+#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/indexed_db_info.h"
#include "content/public/common/content_switches.h"
+#include "ui/base/text/bytes_formatting.h"
#include "webkit/browser/database/database_util.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/browser/quota/special_storage_policy.h"
#include "webkit/common/database/database_identifier.h"
+using base::DictionaryValue;
+using base::ListValue;
using webkit_database::DatabaseUtil;
namespace content {
@@ -105,13 +113,13 @@ IndexedDBContextImpl::IndexedDBContextImpl(
IndexedDBFactory* IndexedDBContextImpl::GetIDBFactory() {
DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
- if (!idb_factory_) {
+ if (!factory_) {
// Prime our cache of origins with existing databases so we can
// detect when dbs are newly created.
GetOriginSet();
- idb_factory_ = new IndexedDBFactory();
+ factory_ = new IndexedDBFactory();
}
- return idb_factory_;
+ return factory_;
}
std::vector<GURL> IndexedDBContextImpl::GetAllOrigins() {
@@ -146,6 +154,98 @@ std::vector<IndexedDBInfo> IndexedDBContextImpl::GetAllOriginsInfo() {
return result;
}
+static bool HostNameComparator(const GURL& i, const GURL& j) {
+ return i.host() < j.host();
+}
+
+ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
+ DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
+ std::vector<GURL> origins = GetAllOrigins();
+
+ std::sort(origins.begin(), origins.end(), HostNameComparator);
+
+ scoped_ptr<ListValue> list(new ListValue());
+ for (std::vector<GURL>::const_iterator iter = origins.begin();
+ iter != origins.end();
+ ++iter) {
+ const GURL& origin_url = *iter;
+
+ scoped_ptr<DictionaryValue> info(new DictionaryValue());
+ info->SetString("url", origin_url.spec());
+ info->SetString("size", ui::FormatBytes(GetOriginDiskUsage(origin_url)));
+ info->SetDouble("last_modified",
+ GetOriginLastModified(origin_url).ToJsTime());
+ info->SetString("path", GetFilePath(origin_url).value());
+ info->SetDouble("connection_count", GetConnectionCount(origin_url));
+
+ // This ends up being O(n^2) since we iterate over all open databases
+ // to extract just those in the origin, and we're iterating over all
+ // origins in the outer loop.
+
+ if (factory_) {
+ std::vector<IndexedDBDatabase*> databases =
+ factory_->GetOpenDatabasesForOrigin(
+ webkit_database::GetIdentifierFromOrigin(origin_url));
+ // TODO(jsbell): Sort by name?
+ scoped_ptr<ListValue> database_list(new ListValue());
+
+ for (std::vector<IndexedDBDatabase*>::iterator it = databases.begin();
+ it != databases.end();
+ ++it) {
+
+ const IndexedDBDatabase* db = *it;
+ scoped_ptr<DictionaryValue> db_info(new DictionaryValue());
+
+ db_info->SetString("name", db->name());
+ db_info->SetDouble("pending_opens", db->PendingOpenCount());
+ db_info->SetDouble("pending_upgrades", db->PendingUpgradeCount());
+ db_info->SetDouble("running_upgrades", db->RunningUpgradeCount());
+ db_info->SetDouble("pending_deletes", db->PendingDeleteCount());
+ db_info->SetDouble("connection_count",
+ db->ConnectionCount() - db->PendingUpgradeCount() -
+ db->RunningUpgradeCount());
+
+ scoped_ptr<ListValue> transaction_list(new ListValue());
+ std::vector<const IndexedDBTransaction*> transactions =
+ db->transaction_coordinator().GetTransactions();
+ for (std::vector<const IndexedDBTransaction*>::iterator trans_it =
+ transactions.begin();
+ trans_it != transactions.end();
+ ++trans_it) {
+
+ const IndexedDBTransaction* transaction = *trans_it;
+ scoped_ptr<DictionaryValue> transaction_info(new DictionaryValue());
+
+ const char* kModes[] = { "readonly", "readwrite", "versionchange" };
+ transaction_info->SetString("mode", kModes[transaction->mode()]);
+ transaction_info->SetBoolean("running", transaction->IsRunning());
+
+ scoped_ptr<ListValue> scope(new ListValue());
+ for (std::set<int64>::const_iterator scope_it =
+ transaction->scope().begin();
+ scope_it != transaction->scope().end();
+ ++scope_it) {
+ IndexedDBDatabaseMetadata::ObjectStoreMap::const_iterator it =
+ db->metadata().object_stores.find(*scope_it);
+ if (it != db->metadata().object_stores.end())
+ scope->AppendString(it->second.name);
+ }
+
+ transaction_info->Set("scope", scope.release());
+ transaction_list->Append(transaction_info.release());
+ }
+ db_info->Set("transactions", transaction_list.release());
+
+ database_list->Append(db_info.release());
+ }
+ info->Set("databases", database_list.release());
+ }
+
+ list->Append(info.release());
+ }
+ return list.release();
+}
+
int64 IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
if (data_path_.empty() || !IsInOriginSet(origin_url))
@@ -297,10 +397,10 @@ quota::QuotaManagerProxy* IndexedDBContextImpl::quota_manager_proxy() {
}
IndexedDBContextImpl::~IndexedDBContextImpl() {
- if (idb_factory_) {
- IndexedDBFactory* factory = idb_factory_;
+ if (factory_) {
+ IndexedDBFactory* factory = factory_;
factory->AddRef();
- idb_factory_ = NULL;
+ factory_ = NULL;
if (!task_runner_->ReleaseSoon(FROM_HERE, factory)) {
factory->Release();
}
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index 4b23982..3c76465 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -22,6 +22,7 @@
class GURL;
namespace base {
+class ListValue;
class FilePath;
class SequencedTaskRunner;
}
@@ -73,6 +74,7 @@ class CONTENT_EXPORT IndexedDBContextImpl
quota::QuotaManagerProxy* quota_manager_proxy();
+ base::ListValue* GetAllOriginsDetails();
void ForceClose(const GURL& origin_url);
base::FilePath GetFilePath(const GURL& origin_url);
base::FilePath data_path() const { return data_path_; }
@@ -122,7 +124,7 @@ class CONTENT_EXPORT IndexedDBContextImpl
// Only for testing.
void ResetCaches();
- scoped_refptr<IndexedDBFactory> idb_factory_;
+ scoped_refptr<IndexedDBFactory> factory_;
base::FilePath data_path_;
// If true, nothing (not even session-only data) should be deleted on exit.
bool force_keep_session_state_;
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 73d2b88..9eb5774 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -457,7 +457,7 @@ scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create(
const string16& name,
IndexedDBBackingStore* database,
IndexedDBFactory* factory,
- const string16& unique_identifier) {
+ const Identifier& unique_identifier) {
scoped_refptr<IndexedDBDatabase> backend =
new IndexedDBDatabase(name, database, factory, unique_identifier);
if (!backend->OpenInternal())
@@ -474,10 +474,11 @@ bool Contains(const T& container, const U& item) {
}
}
-IndexedDBDatabase::IndexedDBDatabase(const string16& name,
- IndexedDBBackingStore* backing_store,
- IndexedDBFactory* factory,
- const string16& unique_identifier)
+IndexedDBDatabase::IndexedDBDatabase(
+ const string16& name,
+ IndexedDBBackingStore* backing_store,
+ IndexedDBFactory* factory,
+ const Identifier& unique_identifier)
: backing_store_(backing_store),
metadata_(name,
kInvalidId,
@@ -1558,6 +1559,22 @@ size_t IndexedDBDatabase::ConnectionCount() const {
return connections_.size();
}
+size_t IndexedDBDatabase::PendingOpenCount() const {
+ return pending_open_calls_.size();
+}
+
+size_t IndexedDBDatabase::PendingUpgradeCount() const {
+ return pending_run_version_change_transaction_call_ ? 1 : 0;
+}
+
+size_t IndexedDBDatabase::RunningUpgradeCount() const {
+ return pending_second_half_open_ ? 1 : 0;
+}
+
+size_t IndexedDBDatabase::PendingDeleteCount() const {
+ return pending_delete_calls_.size();
+}
+
void IndexedDBDatabase::ProcessPendingCalls() {
if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) {
DCHECK(pending_run_version_change_transaction_call_->Version() >
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h
index a239669..9c617f5 100644
--- a/content/browser/indexed_db/indexed_db_database.h
+++ b/content/browser/indexed_db/indexed_db_database.h
@@ -44,6 +44,8 @@ class CONTENT_EXPORT IndexedDBDatabase
};
typedef std::vector<IndexedDBKey> IndexKeys;
+ // Identifier is pair of (origin identifier, database name).
+ typedef std::pair<std::string, base::string16> Identifier;
static const int64 kInvalidId = 0;
static const int64 kMinimumIndexId = 30;
@@ -52,10 +54,12 @@ class CONTENT_EXPORT IndexedDBDatabase
const string16& name,
IndexedDBBackingStore* database,
IndexedDBFactory* factory,
- const string16& unique_identifier);
+ const Identifier& unique_identifier);
scoped_refptr<IndexedDBBackingStore> BackingStore() const;
int64 id() const { return metadata_.id; }
+ const base::string16& name() const { return metadata_.name; }
+
void AddObjectStore(const IndexedDBObjectStoreMetadata& metadata,
int64 new_max_object_store_id);
void RemoveObjectStore(int64 object_store_id);
@@ -106,6 +110,9 @@ class CONTENT_EXPORT IndexedDBDatabase
IndexedDBTransactionCoordinator& transaction_coordinator() {
return transaction_coordinator_;
}
+ const IndexedDBTransactionCoordinator& transaction_coordinator() const {
+ return transaction_coordinator_;
+ }
void TransactionStarted(IndexedDBTransaction* transaction);
void TransactionFinished(IndexedDBTransaction* transaction);
@@ -155,13 +162,25 @@ class CONTENT_EXPORT IndexedDBDatabase
int64 object_store_id,
scoped_refptr<IndexedDBCallbacks> callbacks);
+ // Number of connections that have progressed passed initial open call.
+ size_t ConnectionCount() const;
+ // Number of open calls that are blocked on other connections.
+ size_t PendingOpenCount() const;
+ // Number of pending upgrades (0 or 1). Also included in ConnectionCount().
+ size_t PendingUpgradeCount() const;
+ // Number of running upgrades (0 or 1). Also included in ConnectionCount().
+ size_t RunningUpgradeCount() const;
+ // Number of pending deletes, blocked on other connections.
+ size_t PendingDeleteCount() const;
+
private:
friend class base::RefCounted<IndexedDBDatabase>;
- IndexedDBDatabase(const string16& name,
- IndexedDBBackingStore* database,
- IndexedDBFactory* factory,
- const string16& unique_identifier);
+ IndexedDBDatabase(
+ const string16& name,
+ IndexedDBBackingStore* database,
+ IndexedDBFactory* factory,
+ const Identifier& unique_identifier);
~IndexedDBDatabase();
bool IsOpenConnectionBlocked() const;
@@ -182,7 +201,6 @@ class CONTENT_EXPORT IndexedDBDatabase
int64 transaction_id,
int64 requested_version,
WebKit::WebIDBCallbacks::DataLoss data_loss);
- size_t ConnectionCount() const;
void ProcessPendingCalls();
bool IsDeleteDatabaseBlocked() const;
@@ -207,7 +225,7 @@ class CONTENT_EXPORT IndexedDBDatabase
scoped_refptr<IndexedDBBackingStore> backing_store_;
IndexedDBDatabaseMetadata metadata_;
- string16 identifier_;
+ const Identifier identifier_;
// This might not need to be a scoped_refptr since the factory's lifetime is
// that of the page group, but it's better to be conservitive than sorry.
scoped_refptr<IndexedDBFactory> factory_;
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc
index c1d1a349..fad9910 100644
--- a/content/browser/indexed_db/indexed_db_database_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -29,7 +29,10 @@ TEST(IndexedDBDatabaseTest, BackingStoreRetention) {
IndexedDBFactory* factory = 0;
scoped_refptr<IndexedDBDatabase> db = IndexedDBDatabase::Create(
- ASCIIToUTF16("db"), backing_store, factory, ASCIIToUTF16("uniqueid"));
+ ASCIIToUTF16("db"),
+ backing_store,
+ factory,
+ IndexedDBDatabase::Identifier());
EXPECT_FALSE(backing_store->HasOneRef()); // local and db
db = NULL;
EXPECT_TRUE(backing_store->HasOneRef()); // local
@@ -71,8 +74,11 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) {
EXPECT_TRUE(backing_store->HasOneRef()); // local
IndexedDBFactory* factory = 0;
- scoped_refptr<IndexedDBDatabase> db = IndexedDBDatabase::Create(
- ASCIIToUTF16("db"), backing_store, factory, ASCIIToUTF16("uniqueid"));
+ scoped_refptr<IndexedDBDatabase> db =
+ IndexedDBDatabase::Create(ASCIIToUTF16("db"),
+ backing_store,
+ factory,
+ IndexedDBDatabase::Identifier());
EXPECT_FALSE(backing_store->HasOneRef()); // local and db
@@ -128,8 +134,11 @@ TEST(IndexedDBDatabaseTest, ForcedClose) {
EXPECT_TRUE(backing_store->HasOneRef());
IndexedDBFactory* factory = 0;
- scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create(
- ASCIIToUTF16("db"), backing_store, factory, ASCIIToUTF16("uniqueid"));
+ scoped_refptr<IndexedDBDatabase> database =
+ IndexedDBDatabase::Create(ASCIIToUTF16("db"),
+ backing_store,
+ factory,
+ IndexedDBDatabase::Identifier());
EXPECT_FALSE(backing_store->HasOneRef()); // local and db
@@ -182,8 +191,11 @@ TEST(IndexedDBDatabaseTest, PendingDelete) {
EXPECT_TRUE(backing_store->HasOneRef()); // local
IndexedDBFactory* factory = 0;
- scoped_refptr<IndexedDBDatabase> db = IndexedDBDatabase::Create(
- ASCIIToUTF16("db"), backing_store, factory, ASCIIToUTF16("uniqueid"));
+ scoped_refptr<IndexedDBDatabase> db =
+ IndexedDBDatabase::Create(ASCIIToUTF16("db"),
+ backing_store,
+ factory,
+ IndexedDBDatabase::Identifier());
EXPECT_FALSE(backing_store->HasOneRef()); // local and db
diff --git a/content/browser/indexed_db/indexed_db_factory.cc b/content/browser/indexed_db/indexed_db_factory.cc
index eb7fa81..6b8d0c8 100644
--- a/content/browser/indexed_db/indexed_db_factory.cc
+++ b/content/browser/indexed_db/indexed_db_factory.cc
@@ -7,7 +7,6 @@
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
-#include "content/browser/indexed_db/indexed_db_database.h"
#include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction_coordinator.h"
#include "third_party/WebKit/public/platform/WebIDBDatabaseException.h"
@@ -31,17 +30,12 @@ static std::string ComputeFileIdentifier(const std::string& origin_identifier) {
return origin_identifier + "@1";
}
-static string16 ComputeUniqueIdentifier(const string16& name,
- const std::string& origin_identifier) {
- return ASCIIToUTF16(ComputeFileIdentifier(origin_identifier)) + name;
-}
-
IndexedDBFactory::IndexedDBFactory() {}
IndexedDBFactory::~IndexedDBFactory() {}
void IndexedDBFactory::RemoveIDBDatabaseBackend(
- const string16& unique_identifier) {
+ const IndexedDBDatabase::Identifier& unique_identifier) {
DCHECK(database_backend_map_.find(unique_identifier) !=
database_backend_map_.end());
database_backend_map_.erase(unique_identifier);
@@ -73,9 +67,7 @@ void IndexedDBFactory::DeleteDatabase(
const std::string& origin_identifier,
const base::FilePath& data_directory) {
IDB_TRACE("IndexedDBFactory::DeleteDatabase");
- const string16 unique_identifier =
- ComputeUniqueIdentifier(name, origin_identifier);
-
+ IndexedDBDatabase::Identifier unique_identifier(origin_identifier, name);
IndexedDBDatabaseMap::iterator it =
database_backend_map_.find(unique_identifier);
if (it != database_backend_map_.end()) {
@@ -158,10 +150,8 @@ void IndexedDBFactory::Open(
const std::string& origin_identifier,
const base::FilePath& data_directory) {
IDB_TRACE("IndexedDBFactory::Open");
- const string16 unique_identifier =
- ComputeUniqueIdentifier(name, origin_identifier);
-
scoped_refptr<IndexedDBDatabase> database_backend;
+ IndexedDBDatabase::Identifier unique_identifier(origin_identifier, name);
IndexedDBDatabaseMap::iterator it =
database_backend_map_.find(unique_identifier);
WebKit::WebIDBCallbacks::DataLoss data_loss =
@@ -196,4 +186,15 @@ void IndexedDBFactory::Open(
callbacks, database_callbacks, transaction_id, version, data_loss);
}
+std::vector<IndexedDBDatabase*> IndexedDBFactory::GetOpenDatabasesForOrigin(
+ const std::string& origin_identifier) const {
+ std::vector<IndexedDBDatabase*> result;
+ for (IndexedDBDatabaseMap::const_iterator it = database_backend_map_.begin();
+ it != database_backend_map_.end(); ++it) {
+ if (it->first.first == origin_identifier)
+ result.push_back(it->second.get());
+ }
+ return result;
+}
+
} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_factory.h b/content/browser/indexed_db/indexed_db_factory.h
index 0345b15..1666af5 100644
--- a/content/browser/indexed_db/indexed_db_factory.h
+++ b/content/browser/indexed_db/indexed_db_factory.h
@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
+#include "content/browser/indexed_db/indexed_db_database.h"
#include "content/browser/indexed_db/indexed_db_database_callbacks.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
#include "content/common/content_export.h"
@@ -21,7 +22,6 @@
namespace content {
class IndexedDBBackingStore;
-class IndexedDBDatabase;
class CONTENT_EXPORT IndexedDBFactory
: NON_EXPORTED_BASE(public base::RefCounted<IndexedDBFactory>) {
@@ -29,7 +29,8 @@ class CONTENT_EXPORT IndexedDBFactory
IndexedDBFactory();
// Notifications from weak pointers.
- void RemoveIDBDatabaseBackend(const string16& unique_identifier);
+ void RemoveIDBDatabaseBackend(
+ const IndexedDBDatabase::Identifier& unique_identifier);
void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks,
const std::string& origin_identifier,
@@ -47,6 +48,10 @@ class CONTENT_EXPORT IndexedDBFactory
const std::string& origin_identifier,
const base::FilePath& data_directory);
+ // Iterates over all databases; for diagnostics only.
+ std::vector<IndexedDBDatabase*> GetOpenDatabasesForOrigin(
+ const std::string& origin_identifier) const;
+
protected:
friend class base::RefCounted<IndexedDBFactory>;
@@ -58,8 +63,8 @@ class CONTENT_EXPORT IndexedDBFactory
WebKit::WebIDBCallbacks::DataLoss* data_loss);
private:
- typedef std::map<string16, scoped_refptr<IndexedDBDatabase> >
- IndexedDBDatabaseMap;
+ typedef std::map<IndexedDBDatabase::Identifier,
+ scoped_refptr<IndexedDBDatabase> > IndexedDBDatabaseMap;
IndexedDBDatabaseMap database_backend_map_;
typedef std::map<std::string, base::WeakPtr<IndexedDBBackingStore> >
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.cc b/content/browser/indexed_db/indexed_db_internals_ui.cc
index 1b2451f..a5c90c4 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -4,7 +4,6 @@
#include "content/browser/indexed_db/indexed_db_internals_ui.h"
-#include <algorithm>
#include <string>
#include "base/bind.h"
@@ -83,18 +82,14 @@ void IndexedDBInternalsUI::GetAllOrigins(const base::ListValue* args) {
BrowserContext::ForEachStoragePartition(browser_context, cb);
}
-static bool HostNameComparator(const IndexedDBInfo& i, const IndexedDBInfo& j) {
- return i.origin_.host() < j.origin_.host();
-}
-
void IndexedDBInternalsUI::GetAllOriginsOnIndexedDBThread(
scoped_refptr<IndexedDBContext> context,
const base::FilePath& context_path) {
DCHECK(context->TaskRunner()->RunsTasksOnCurrentThread());
- scoped_ptr<std::vector<IndexedDBInfo> > info_list(
- new std::vector<IndexedDBInfo>(context->GetAllOriginsInfo()));
- std::sort(info_list->begin(), info_list->end(), HostNameComparator);
+ scoped_ptr<ListValue> info_list(static_cast<IndexedDBContextImpl*>(
+ context.get())->GetAllOriginsDetails());
+
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&IndexedDBInternalsUI::OnOriginsReady,
@@ -103,24 +98,11 @@ void IndexedDBInternalsUI::GetAllOriginsOnIndexedDBThread(
context_path));
}
-void IndexedDBInternalsUI::OnOriginsReady(
- scoped_ptr<std::vector<IndexedDBInfo> > origins,
- const base::FilePath& path) {
+void IndexedDBInternalsUI::OnOriginsReady(scoped_ptr<ListValue> origins,
+ const base::FilePath& path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- base::ListValue urls;
- for (std::vector<IndexedDBInfo>::const_iterator iter = origins->begin();
- iter != origins->end();
- ++iter) {
- base::DictionaryValue* info = new base::DictionaryValue;
- info->SetString("url", iter->origin_.spec());
- info->SetString("size", ui::FormatBytes(iter->size_));
- info->SetDouble("last_modified", iter->last_modified_.ToJsTime());
- info->SetString("path", iter->path_.value());
- info->SetDouble("connection_count", iter->connection_count_);
- urls.Append(info);
- }
web_ui()->CallJavascriptFunction(
- "indexeddb.onOriginsReady", urls, base::StringValue(path.value()));
+ "indexeddb.onOriginsReady", *origins, base::StringValue(path.value()));
}
static void FindContext(const base::FilePath& partition_path,
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.h b/content/browser/indexed_db/indexed_db_internals_ui.h
index 3ec1925..a196e03 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.h
+++ b/content/browser/indexed_db/indexed_db_internals_ui.h
@@ -33,7 +33,7 @@ class IndexedDBInternalsUI : public WebUIController {
void GetAllOrigins(const base::ListValue* args);
void GetAllOriginsOnIndexedDBThread(scoped_refptr<IndexedDBContext> context,
const base::FilePath& context_path);
- void OnOriginsReady(scoped_ptr<std::vector<IndexedDBInfo> > origins,
+ void OnOriginsReady(scoped_ptr<base::ListValue> origins,
const base::FilePath& path);
void AddContextFromStoragePartition(StoragePartition* partition);
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h
index 4c37528..51b1c0a 100644
--- a/content/browser/indexed_db/indexed_db_transaction.h
+++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -69,6 +69,7 @@ class IndexedDBTransaction : public base::RefCounted<IndexedDBTransaction> {
IndexedDBDatabase* database() const { return database_; }
IndexedDBDatabaseCallbacks* connection() const { return callbacks_; }
+ bool IsRunning() const { return state_ == RUNNING; }
protected:
virtual ~IndexedDBTransaction();
diff --git a/content/browser/indexed_db/indexed_db_transaction_coordinator.cc b/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
index 78825b8..1f5100d 100644
--- a/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
+++ b/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
@@ -37,11 +37,10 @@ void IndexedDBTransactionCoordinator::DidFinishTransaction(
DCHECK(transactions_.find(transaction) != transactions_.end());
if (queued_transactions_.has(transaction)) {
- DCHECK(started_transactions_.find(transaction) ==
- started_transactions_.end());
+ DCHECK(!started_transactions_.has(transaction));
queued_transactions_.erase(transaction);
} else {
- if (started_transactions_.find(transaction) != started_transactions_.end())
+ if (started_transactions_.has(transaction))
started_transactions_.erase(transaction);
}
transactions_.erase(transaction);
@@ -56,7 +55,7 @@ bool IndexedDBTransactionCoordinator::IsActive(
bool found = false;
if (queued_transactions_.has(transaction))
found = true;
- if (started_transactions_.find(transaction) != started_transactions_.end()) {
+ if (started_transactions_.has(transaction)) {
DCHECK(!found);
found = true;
}
@@ -65,6 +64,26 @@ bool IndexedDBTransactionCoordinator::IsActive(
}
#endif
+std::vector<const IndexedDBTransaction*>
+IndexedDBTransactionCoordinator::GetTransactions() const {
+ std::vector<const IndexedDBTransaction*> result;
+
+ for (list_set<IndexedDBTransaction*>::const_iterator it =
+ started_transactions_.begin();
+ it != started_transactions_.end();
+ ++it) {
+ result.push_back(*it);
+ }
+ for (list_set<IndexedDBTransaction*>::const_iterator it =
+ queued_transactions_.begin();
+ it != queued_transactions_.end();
+ ++it) {
+ result.push_back(*it);
+ }
+
+ return result;
+}
+
void IndexedDBTransactionCoordinator::ProcessStartedTransactions() {
if (queued_transactions_.empty())
return;
@@ -109,7 +128,7 @@ bool IndexedDBTransactionCoordinator::CanRunTransaction(
return true;
case indexed_db::TRANSACTION_READ_WRITE:
- for (std::set<IndexedDBTransaction*>::const_iterator it =
+ for (list_set<IndexedDBTransaction*>::const_iterator it =
started_transactions_.begin();
it != started_transactions_.end();
++it) {
diff --git a/content/browser/indexed_db/indexed_db_transaction_coordinator.h b/content/browser/indexed_db/indexed_db_transaction_coordinator.h
index 1b0eed1..d9f9cd5 100644
--- a/content/browser/indexed_db/indexed_db_transaction_coordinator.h
+++ b/content/browser/indexed_db/indexed_db_transaction_coordinator.h
@@ -7,6 +7,7 @@
#include <map>
#include <set>
+#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -31,6 +32,9 @@ class IndexedDBTransactionCoordinator {
bool IsActive(IndexedDBTransaction* transaction);
#endif
+ // Makes a snapshot of the transaction queue. For diagnostics only.
+ std::vector<const IndexedDBTransaction*> GetTransactions() const;
+
private:
void ProcessStartedTransactions();
bool CanRunTransaction(IndexedDBTransaction* transaction);
@@ -38,9 +42,12 @@ class IndexedDBTransactionCoordinator {
// This is just an efficient way to keep references to all transactions.
std::map<IndexedDBTransaction*, scoped_refptr<IndexedDBTransaction> >
transactions_;
+
// Transactions in different states are grouped below.
+ // list_set is used to provide stable ordering; required by spec
+ // for the queue, convenience for diagnostics for the rest.
list_set<IndexedDBTransaction*> queued_transactions_;
- std::set<IndexedDBTransaction*> started_transactions_;
+ list_set<IndexedDBTransaction*> started_transactions_;
};
} // namespace content
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.css b/content/browser/resources/indexed_db/indexeddb_internals.css
index 2bbea77..76653f0 100644
--- a/content/browser/resources/indexed_db/indexeddb_internals.css
+++ b/content/browser/resources/indexed_db/indexeddb_internals.css
@@ -29,6 +29,43 @@
white-space: nowrap;
}
+.indexeddb-database {
+ margin-bottom: 6px;
+ margin-top: 6px;
+ margin-left: 12px;
+
+ position: relative;
+}
+
+.indexeddb-database > div {
+ margin-left: 12px;
+}
+
+.indexeddb-connection-count {
+ margin: 0 8px;
+}
+.indexeddb-connection-count.pending {
+ font-weight: bold;
+}
+
+.indexeddb-transaction {
+ background-color: rgb(235, 239, 249);
+ margin: 4px 0;
+ border-radius: 4px;
+ padding: 2px;
+ position: relative;
+}
+
+.indexeddb-transaction.running {
+ font-weight: bold;
+}
+
+.indexeddb-transaction-mode,
+.indexeddb-transaction-scope,
+.indexeddb-transaction-state {
+ margin: 0 8px;
+}
+
.controls a {
-webkit-margin-end: 16px;
color: #777;
diff --git a/content/browser/resources/indexed_db/indexeddb_internals.html b/content/browser/resources/indexed_db/indexeddb_internals.html
index 0625079..153aef1 100644
--- a/content/browser/resources/indexed_db/indexeddb_internals.html
+++ b/content/browser/resources/indexed_db/indexeddb_internals.html
@@ -45,6 +45,57 @@
jsvalues=".idb_origin_url:url;.idb_partition_path:$partition_path">Download</a>
<span class="download-status" style="display: none">Loading...</span>
</div>
+ <div class="indexeddb-database" jsselect="$this.databases">
+
+ <span>Open database:</span>
+ <span jscontent="name"></span>
+
+ <div>
+ <span>Connections:</span>
+
+ <span class="indexeddb-connection-count"
+ jsdisplay="connection_count">
+ <span>open:</span>
+ <span jscontent="connection_count"></span>
+ </span>
+
+ <span class="indexeddb-connection-count pending"
+ jsdisplay="pending_opens">
+ <span>pending opens:</span>
+ <span jscontent="pending_opens"></span>
+ </span>
+
+ <span class="indexeddb-connection-count pending"
+ jsdisplay="pending_upgrades">
+ <span>pending upgrades:</span>
+ <span jscontent="pending_upgrades"></span>
+ </span>
+
+ <span class="indexeddb-connection-count pending"
+ jsdisplay="running_upgrades">
+ <span>running upgrades:</span>
+ <span jscontent="running_upgrades"></span>
+ </span>
+
+ <span class="indexeddb-connection-count pending"
+ jsdisplay="pending_deletes">
+ <span>pending deletes:</span>
+ <span jscontent="pending_deletes"></span>
+ </span>
+
+ </div>
+ <div class="indexeddb-transaction"
+ jsselect="$this.transactions"
+ jseval="this.classList.add($this.running ? 'running' : 'waiting')">
+ <span>Transaction:</span>
+ <span class="indexeddb-transaction-mode" jscontent="mode"></span>
+ <span class="indexeddb-transaction-scope" jsdisplay="scope">
+ <span>scope:</span> <span jscontent="'[ ' + scope.join(', ') + ' ]'"></span>
+ </span>
+ <span class="indexeddb-transaction-state"
+ jscontent="running ? '(running)' : '(blocked)'"></span>
+ </div>
+ </div>
</div>
</div>
</div>