IndexedDB: Create IDBTransaction interface
This CL creates a bare IDBTransaction interface with just the
CreateObjectStore method. Later CLs will be responsible for
moving the remaining methods from IDBDatabase to IDBTransaction.
Bug: 717812
Change-Id: Ie1e084957e66f2afef563d37af9243726e48855b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1526172
Reviewed-by: Kinuko Yasuda <[email protected]>
Reviewed-by: Tom Sepez <[email protected]>
Reviewed-by: Daniel Murphy <[email protected]>
Commit-Queue: Chase Phillips <[email protected]>
Cr-Commit-Position: refs/heads/master@{#643406}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 49ab076..faf64e2 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1056,6 +1056,8 @@
"indexed_db/scopes/scope_lock_range.h",
"indexed_db/scopes/scopes_lock_manager.cc",
"indexed_db/scopes/scopes_lock_manager.h",
+ "indexed_db/transaction_impl.cc",
+ "indexed_db/transaction_impl.h",
"initiator_csp_context.cc",
"initiator_csp_context.h",
"installedapp/installed_app_provider_impl_default.cc",
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc
index 3b3501a..e25f073c 100644
--- a/content/browser/indexed_db/database_impl.cc
+++ b/content/browser/indexed_db/database_impl.cc
@@ -20,6 +20,7 @@
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/indexed_db_value.h"
+#include "content/browser/indexed_db/transaction_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/blob/blob_storage_context.h"
@@ -108,24 +109,6 @@
indexed_db_context_->ConnectionClosed(origin_, connection_.get());
}
-void DatabaseImpl::CreateObjectStore(int64_t transaction_id,
- int64_t object_store_id,
- const base::string16& name,
- const IndexedDBKeyPath& key_path,
- bool auto_increment) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!connection_->IsConnected())
- return;
-
- IndexedDBTransaction* transaction =
- connection_->GetTransaction(transaction_id);
- if (!transaction)
- return;
-
- connection_->database()->CreateObjectStore(transaction, object_store_id, name,
- key_path, auto_increment);
-}
-
void DatabaseImpl::DeleteObjectStore(int64_t transaction_id,
int64_t object_store_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -157,6 +140,7 @@
}
void DatabaseImpl::CreateTransaction(
+ blink::mojom::IDBTransactionAssociatedRequest transaction_request,
int64_t transaction_id,
const std::vector<int64_t>& object_store_ids,
blink::mojom::IDBTransactionMode mode) {
@@ -175,6 +159,9 @@
new IndexedDBBackingStore::Transaction(
connection_->database()->backing_store()));
connection_->database()->RegisterAndScheduleTransaction(transaction);
+
+ dispatcher_host_->CreateAndBindTransactionImpl(
+ std::move(transaction_request), origin_, transaction->AsWeakPtr());
}
void DatabaseImpl::Close() {
diff --git a/content/browser/indexed_db/database_impl.h b/content/browser/indexed_db/database_impl.h
index 3c17ea0..95753217 100644
--- a/content/browser/indexed_db/database_impl.h
+++ b/content/browser/indexed_db/database_impl.h
@@ -38,19 +38,16 @@
~DatabaseImpl() override;
// blink::mojom::IDBDatabase implementation
- void CreateObjectStore(int64_t transaction_id,
- int64_t object_store_id,
- const base::string16& name,
- const blink::IndexedDBKeyPath& key_path,
- bool auto_increment) override;
void DeleteObjectStore(int64_t transaction_id,
int64_t object_store_id) override;
void RenameObjectStore(int64_t transaction_id,
int64_t object_store_id,
const base::string16& new_name) override;
- void CreateTransaction(int64_t transaction_id,
- const std::vector<int64_t>& object_store_ids,
- blink::mojom::IDBTransactionMode mode) override;
+ void CreateTransaction(
+ blink::mojom::IDBTransactionAssociatedRequest transaction_request,
+ int64_t transaction_id,
+ const std::vector<int64_t>& object_store_ids,
+ blink::mojom::IDBTransactionMode mode) override;
void Close() override;
void VersionChangeIgnored() override;
void AddObserver(int64_t transaction_id,
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc
index 12cd64d..4a15e694 100644
--- a/content/browser/indexed_db/indexed_db_database.cc
+++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -3,8 +3,8 @@
// found in the LICENSE file.
#include "content/browser/indexed_db/indexed_db_database.h"
-#include <math.h>
+#include <math.h>
#include <algorithm>
#include <limits>
#include <set>
@@ -35,6 +35,7 @@
#include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/scopes/scope_lock.h"
#include "content/browser/indexed_db/scopes/scopes_lock_manager.h"
+#include "content/browser/indexed_db/transaction_impl.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_channel.h"
#include "storage/browser/blob/blob_data_handle.h"
@@ -269,6 +270,11 @@
std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()),
blink::mojom::IDBTransactionMode::VersionChange,
new IndexedDBBackingStore::Transaction(db_->backing_store()));
+
+ // Create transaction binding.
+ std::move(pending_->create_transaction_callback)
+ .Run(transaction->AsWeakPtr());
+
transaction->ScheduleTask(
base::BindOnce(&IndexedDBDatabase::VersionChangeOperation, db_,
pending_->version, pending_->callbacks));
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc
index 7afd674..af626a4 100644
--- a/content/browser/indexed_db/indexed_db_database_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -45,6 +45,12 @@
}
namespace content {
+namespace {
+
+void CreateAndBindTransactionPlaceholder(
+ base::WeakPtr<IndexedDBTransaction> transaction) {}
+
+} // namespace
class IndexedDBDatabaseTest : public ::testing::Test {
public:
@@ -89,10 +95,13 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection1(
std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback1)));
db_->OpenConnection(std::move(connection1));
EXPECT_FALSE(backing_store_->HasOneRef()); // db, connection count > 0
@@ -101,10 +110,13 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id2 = 2;
+ auto create_transaction_callback2 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection2(
std::make_unique<IndexedDBPendingConnection>(
request2, callbacks2, kFakeChildProcessId, transaction_id2,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback2)));
db_->OpenConnection(std::move(connection2));
EXPECT_FALSE(backing_store_->HasOneRef()); // local and connection
@@ -128,10 +140,13 @@
new MockIndexedDBDatabaseCallbacks());
scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks());
const int64_t upgrade_transaction_id = 3;
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection(
std::make_unique<IndexedDBPendingConnection>(
request, callbacks, kFakeChildProcessId, upgrade_transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback)));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(db_.get(), request->connection()->database());
@@ -182,10 +197,13 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection(
std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback1)));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(db_->ConnectionCount(), 1UL);
@@ -226,10 +244,12 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection1(
std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
- kDatabaseVersion));
+ kDatabaseVersion, std::move(create_transaction_callback1)));
db_->OpenConnection(std::move(connection1));
EXPECT_EQ(db_->ConnectionCount(), 1UL);
@@ -242,10 +262,12 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id2 = 2;
+ auto create_transaction_callback2 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection2(
std::make_unique<IndexedDBPendingConnection>(
request2, callbacks2, kFakeChildProcessId, transaction_id2,
- kDatabaseVersion));
+ kDatabaseVersion, std::move(create_transaction_callback2)));
db_->OpenConnection(std::move(connection2));
EXPECT_EQ(db_->ConnectionCount(), 1UL);
@@ -258,10 +280,12 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks3(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id3 = 3;
+ auto create_transaction_callback3 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection3(
std::make_unique<IndexedDBPendingConnection>(
request3, callbacks3, kFakeChildProcessId, transaction_id3,
- kDatabaseVersion));
+ kDatabaseVersion, std::move(create_transaction_callback3)));
db_->OpenConnection(std::move(connection3));
// This causes the active request to call OnUpgradeNeeded on its callbacks.
@@ -292,10 +316,13 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection(
std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback1)));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(db_->ConnectionCount(), 1UL);
@@ -322,10 +349,13 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id1 = 1;
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection(
std::make_unique<IndexedDBPendingConnection>(
request1, callbacks1, kFakeChildProcessId, transaction_id1,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback1)));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(db_->ConnectionCount(), 1UL);
@@ -338,9 +368,12 @@
scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2(
new MockIndexedDBDatabaseCallbacks());
const int64_t transaction_id2 = 2;
+ auto create_transaction_callback2 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection2(
std::make_unique<IndexedDBPendingConnection>(
- request1, callbacks1, kFakeChildProcessId, transaction_id2, 3));
+ request1, callbacks1, kFakeChildProcessId, transaction_id2, 3,
+ std::move(create_transaction_callback2)));
db_->OpenConnection(std::move(connection2));
EXPECT_EQ(db_->ConnectionCount(), 1UL);
@@ -380,10 +413,13 @@
request_ = new MockIndexedDBCallbacks();
callbacks_ = new MockIndexedDBDatabaseCallbacks();
const int64_t transaction_id = 1;
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
std::unique_ptr<IndexedDBPendingConnection> connection(
std::make_unique<IndexedDBPendingConnection>(
request_, callbacks_, kFakeChildProcessId, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback1)));
db_->OpenConnection(std::move(connection));
EXPECT_EQ(IndexedDBDatabaseMetadata::NO_VERSION, db_->metadata().version);
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
index 2667a9e..ec7304f 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -19,6 +19,7 @@
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_database_callbacks.h"
#include "content/browser/indexed_db/indexed_db_pending_connection.h"
+#include "content/browser/indexed_db/transaction_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/blob/blob_storage_context.h"
@@ -108,6 +109,13 @@
cursor_bindings_.RemoveBinding(binding_id);
}
+void IndexedDBDispatcherHost::AddTransactionBinding(
+ std::unique_ptr<blink::mojom::IDBTransaction> transaction,
+ blink::mojom::IDBTransactionAssociatedRequest request) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ transaction_bindings_.AddBinding(std::move(transaction), std::move(request));
+}
+
void IndexedDBDispatcherHost::RenderProcessExited(
RenderProcessHost* host,
const ChildProcessTerminationInfo& info) {
@@ -153,6 +161,7 @@
blink::mojom::IDBDatabaseCallbacksAssociatedPtrInfo database_callbacks_info,
const base::string16& name,
int64_t version,
+ blink::mojom::IDBTransactionAssociatedRequest transaction_request,
int64_t transaction_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -166,12 +175,15 @@
IDBTaskRunner()));
base::FilePath indexed_db_path = indexed_db_context_->data_path();
- // TODO(dgrogan): Don't let a non-existing database be opened (and therefore
- // created) if this origin is already over quota.
+ auto create_transaction_callback = base::BindOnce(
+ &IndexedDBDispatcherHost::CreateAndBindTransactionImpl, AsWeakPtr(),
+ std::move(transaction_request), context.origin);
std::unique_ptr<IndexedDBPendingConnection> connection =
std::make_unique<IndexedDBPendingConnection>(
std::move(callbacks), std::move(database_callbacks), ipc_process_id_,
- transaction_id, version);
+ transaction_id, version, std::move(create_transaction_callback));
+ // TODO(dgrogan): Don't let a non-existing database be opened (and therefore
+ // created) if this origin is already over quota.
indexed_db_context_->GetIDBFactory()->Open(name, std::move(connection),
context.origin, indexed_db_path);
}
@@ -213,11 +225,23 @@
std::move(callback_on_io), context.origin);
}
+void IndexedDBDispatcherHost::CreateAndBindTransactionImpl(
+ blink::mojom::IDBTransactionAssociatedRequest transaction_request,
+ const url::Origin& origin,
+ base::WeakPtr<IndexedDBTransaction> transaction) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ auto transaction_impl = std::make_unique<TransactionImpl>(
+ transaction, origin, this->AsWeakPtr(), IDBTaskRunner());
+ AddTransactionBinding(std::move(transaction_impl),
+ std::move(transaction_request));
+}
+
void IndexedDBDispatcherHost::InvalidateWeakPtrsAndClearBindings() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
weak_factory_.InvalidateWeakPtrs();
cursor_bindings_.CloseAllBindings();
database_bindings_.CloseAllBindings();
+ transaction_bindings_.CloseAllBindings();
}
base::SequencedTaskRunner* IndexedDBDispatcherHost::IDBTaskRunner() const {
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.h b/content/browser/indexed_db/indexed_db_dispatcher_host.h
index 6f166ba3..b12fbea 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host.h
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -35,6 +35,7 @@
namespace content {
class CursorImpl;
class IndexedDBContextImpl;
+class IndexedDBTransaction;
// Constructed on UI thread. All remaining calls (including destruction) should
// happen on the IDB sequenced task runner.
@@ -58,6 +59,10 @@
blink::mojom::IDBCursorAssociatedRequest request);
void RemoveCursorBinding(mojo::BindingId binding_id);
+ void AddTransactionBinding(
+ std::unique_ptr<blink::mojom::IDBTransaction> transaction,
+ blink::mojom::IDBTransactionAssociatedRequest request);
+
// A shortcut for accessing our context.
IndexedDBContextImpl* context() const { return indexed_db_context_.get(); }
scoped_refptr<ChromeBlobStorageContext> blob_storage_context() const {
@@ -70,6 +75,11 @@
return weak_factory_.GetWeakPtr();
}
+ void CreateAndBindTransactionImpl(
+ blink::mojom::IDBTransactionAssociatedRequest transaction_request,
+ const url::Origin& origin,
+ base::WeakPtr<IndexedDBTransaction> transaction);
+
// Called by UI thread. Used to kill outstanding bindings and weak pointers
// in callbacks.
void RenderProcessExited(RenderProcessHost* host,
@@ -94,6 +104,7 @@
database_callbacks_info,
const base::string16& name,
int64_t version,
+ blink::mojom::IDBTransactionAssociatedRequest transaction_request,
int64_t transaction_id) override;
void DeleteDatabase(
blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info,
@@ -120,11 +131,11 @@
};
mojo::BindingSet<blink::mojom::IDBFactory, BindingState> bindings_;
-
mojo::StrongAssociatedBindingSet<blink::mojom::IDBDatabase>
database_bindings_;
-
mojo::StrongAssociatedBindingSet<blink::mojom::IDBCursor> cursor_bindings_;
+ mojo::StrongAssociatedBindingSet<blink::mojom::IDBTransaction>
+ transaction_bindings_;
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
index d46c542c..a6c7e3a 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
@@ -39,8 +39,6 @@
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h"
#include "url/origin.h"
-using blink::mojom::IDBValue;
-using blink::mojom::IDBValuePtr;
using blink::IndexedDBDatabaseMetadata;
using blink::IndexedDBIndexKeys;
using blink::IndexedDBKey;
@@ -53,6 +51,8 @@
using blink::mojom::IDBDatabaseCallbacksAssociatedPtrInfo;
using blink::mojom::IDBFactory;
using blink::mojom::IDBFactoryPtr;
+using blink::mojom::IDBValue;
+using blink::mojom::IDBValuePtr;
using mojo::StrongAssociatedBindingPtr;
using testing::_;
using testing::StrictMock;
@@ -101,11 +101,13 @@
struct TestDatabaseConnection {
TestDatabaseConnection() = default;
- TestDatabaseConnection(url::Origin origin,
+ TestDatabaseConnection(scoped_refptr<base::SequencedTaskRunner> task_runner,
+ url::Origin origin,
base::string16 db_name,
int64_t version,
int64_t upgrade_txn_id)
- : origin(std::move(origin)),
+ : task_runner(std::move(task_runner)),
+ origin(std::move(origin)),
db_name(std::move(db_name)),
version(version),
upgrade_txn_id(upgrade_txn_id),
@@ -119,15 +121,19 @@
void Open(IDBFactory* factory) {
factory->Open(open_callbacks->CreateInterfacePtrAndBind(),
connection_callbacks->CreateInterfacePtrAndBind(), db_name,
- version, upgrade_txn_id);
+ version,
+ mojo::MakeRequest(&version_change_transaction, task_runner),
+ upgrade_txn_id);
}
+ scoped_refptr<base::SequencedTaskRunner> task_runner;
url::Origin origin;
base::string16 db_name;
int64_t version;
int64_t upgrade_txn_id;
IDBDatabaseAssociatedPtr database;
+ blink::mojom::IDBTransactionAssociatedPtr version_change_transaction;
std::unique_ptr<MockMojoIndexedDBCallbacks> open_callbacks;
std::unique_ptr<MockMojoIndexedDBDatabaseCallbacks> connection_callbacks;
@@ -236,7 +242,7 @@
context_impl_->TaskRunner()->PostTask(
FROM_HERE, base::BindLambdaForTesting([&]() {
connection = std::make_unique<TestDatabaseConnection>(
- url::Origin::Create(GURL(kOrigin)),
+ context_impl_->TaskRunner(), url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
@@ -278,8 +284,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
@@ -316,8 +322,9 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
- connection->database->CreateObjectStore(
- kTransactionId, kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
+ connection->version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
blink::IndexedDBKeyPath(), false);
connection->database->Commit(kTransactionId, 0);
}));
@@ -346,7 +353,7 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection 1, and expect the upgrade needed.
connection1 = std::make_unique<TestDatabaseConnection>(
- url::Origin::Create(GURL(kOrigin)),
+ context_impl_->TaskRunner(), url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection1->open_callbacks,
@@ -371,7 +378,8 @@
context_impl_->TaskRunner()->PostTask(
FROM_HERE, base::BindLambdaForTesting([&]() {
connection2 = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion, 0);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, 0);
// Check that we're called in order and the second connection gets it's
// database after the first connection completes.
@@ -396,13 +404,14 @@
connection1->database.Bind(std::move(database_info1));
ASSERT_TRUE(connection1->database.is_bound());
+ ASSERT_TRUE(connection1->version_change_transaction.is_bound());
// Open connection 2, but expect that we won't be called back.
connection2->Open(idb_mojo_factory_.get());
// Create object store.
- connection1->database->CreateObjectStore(
- kTransactionId, kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ connection1->version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
blink::IndexedDBKeyPath(), false);
connection1->database->Commit(kTransactionId, 0);
}));
@@ -436,7 +445,7 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- url::Origin::Create(GURL(kOrigin)),
+ context_impl_->TaskRunner(), url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
@@ -487,8 +496,9 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
- connection->database->CreateObjectStore(
- kTransactionId, kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
+ connection->version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
blink::IndexedDBKeyPath(), false);
// Call Put with an invalid blob.
std::vector<blink::mojom::IDBBlobInfoPtr> blobs;
@@ -539,8 +549,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
IndexedDBDatabaseMetadata::NO_VERSION,
@@ -578,6 +588,8 @@
.WillOnce(RunClosure(quit_closure));
connection->database.Bind(std::move(database_info));
+ ASSERT_TRUE(connection->database.is_bound());
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
connection->database->Commit(kTransactionId, 0);
idb_mojo_factory_->AbortTransactionsAndCompactDatabase(base::BindOnce(
@@ -609,8 +621,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
IndexedDBDatabaseMetadata::NO_VERSION,
@@ -653,8 +665,9 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
- connection->database->CreateObjectStore(
- kTransactionId, kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
+ connection->version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
blink::IndexedDBKeyPath(), false);
idb_mojo_factory_->AbortTransactionsAndCompactDatabase(base::BindOnce(
&StatusCallback, std::move(quit_closure), &callback_result));
@@ -684,8 +697,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
IndexedDBDatabaseMetadata::NO_VERSION,
@@ -728,6 +741,7 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
idb_mojo_factory_->AbortTransactionsAndCompactDatabase(base::BindOnce(
&StatusCallback, std::move(quit_closure), &callback_result));
}));
@@ -757,8 +771,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
{
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(
@@ -801,6 +815,7 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
connection->database->Commit(kTransactionId, 0);
idb_mojo_factory_->AbortTransactionsForDatabase(base::BindOnce(
&StatusCallback, std::move(quit_closure), &callback_result));
@@ -832,8 +847,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
@@ -877,8 +892,9 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
- connection->database->CreateObjectStore(
- kTransactionId, kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
+ connection->version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
blink::IndexedDBKeyPath(), false);
idb_mojo_factory_->AbortTransactionsForDatabase(base::BindOnce(
&StatusCallback, std::move(quit_closure), &callback_result));
@@ -908,8 +924,8 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection.
connection = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion,
- kTransactionId);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion, kTransactionId);
EXPECT_CALL(*connection->open_callbacks,
MockedUpgradeNeeded(IsAssociatedInterfacePtrInfoValid(true),
@@ -953,6 +969,7 @@
connection->database.Bind(std::move(database_info));
ASSERT_TRUE(connection->database.is_bound());
+ ASSERT_TRUE(connection->version_change_transaction.is_bound());
idb_mojo_factory_->AbortTransactionsForDatabase(base::BindOnce(
&StatusCallback, std::move(quit_closure), &callback_result));
}));
@@ -986,9 +1003,9 @@
context_impl_->AddObserver(&observer);
// Open connection 1.
- TestDatabaseConnection connection1(ToOrigin(kOrigin),
- base::UTF8ToUTF16(kDatabaseName),
- kDBVersion1, kTransactionId1);
+ TestDatabaseConnection connection1(
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion1, kTransactionId1);
IndexedDBDatabaseMetadata metadata1;
IDBDatabaseAssociatedPtrInfo database_info1;
EXPECT_EQ(0, observer.notify_list_changed_count);
@@ -1013,6 +1030,8 @@
// Create object store and index.
connection1.database.Bind(std::move(database_info1));
+ ASSERT_TRUE(connection1.database.is_bound());
+ ASSERT_TRUE(connection1.version_change_transaction.is_bound());
{
::testing::InSequence dummy;
base::RunLoop loop;
@@ -1028,9 +1047,9 @@
.WillOnce(RunClosure(std::move(quit_closure)));
ASSERT_TRUE(connection1.database.is_bound());
- connection1.database->CreateObjectStore(kTransactionId1, kObjectStoreId,
- base::UTF8ToUTF16(kObjectStoreName),
- blink::IndexedDBKeyPath(), false);
+ connection1.version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ blink::IndexedDBKeyPath(), false);
connection1.database->CreateIndex(kTransactionId1, kObjectStoreId, kIndexId,
base::UTF8ToUTF16(kIndexName),
blink::IndexedDBKeyPath(), false, false);
@@ -1041,9 +1060,9 @@
connection1.database->Close();
// Open connection 2.
- TestDatabaseConnection connection2(url::Origin::Create(GURL(kOrigin)),
- base::UTF8ToUTF16(kDatabaseName),
- kDBVersion2, kTransactionId2);
+ TestDatabaseConnection connection2(
+ context_impl_->TaskRunner(), url::Origin::Create(GURL(kOrigin)),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion2, kTransactionId2);
IndexedDBDatabaseMetadata metadata2;
IDBDatabaseAssociatedPtrInfo database_info2;
{
@@ -1067,6 +1086,8 @@
// Delete index.
connection2.database.Bind(std::move(database_info2));
+ ASSERT_TRUE(connection2.database.is_bound());
+ ASSERT_TRUE(connection2.version_change_transaction.is_bound());
{
::testing::InSequence dummy;
base::RunLoop loop;
@@ -1091,9 +1112,9 @@
connection2.database->Close();
// Open connection 3.
- TestDatabaseConnection connection3(ToOrigin(kOrigin),
- base::UTF8ToUTF16(kDatabaseName),
- kDBVersion3, kTransactionId3);
+ TestDatabaseConnection connection3(
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion3, kTransactionId3);
IndexedDBDatabaseMetadata metadata3;
IDBDatabaseAssociatedPtrInfo database_info3;
{
@@ -1117,6 +1138,8 @@
// Delete object store.
connection3.database.Bind(std::move(database_info3));
+ ASSERT_TRUE(connection3.database.is_bound());
+ ASSERT_TRUE(connection3.version_change_transaction.is_bound());
{
::testing::InSequence dummy;
base::RunLoop loop;
@@ -1163,7 +1186,7 @@
FROM_HERE, base::BindLambdaForTesting([&]() {
// Open connection 1.
connection1 = std::make_unique<TestDatabaseConnection>(
- url::Origin::Create(GURL(kOrigin)),
+ context_impl_->TaskRunner(), url::Origin::Create(GURL(kOrigin)),
base::UTF8ToUTF16(kDatabaseName), kDBVersion1, kTransactionId1);
EXPECT_CALL(*connection1->open_callbacks,
@@ -1212,10 +1235,10 @@
connection1->database.Bind(std::move(database_info1));
ASSERT_TRUE(connection1->database.is_bound());
- connection1->database->CreateObjectStore(
- kTransactionId1, kObjectStoreId,
- base::UTF8ToUTF16(kObjectStoreName), blink::IndexedDBKeyPath(),
- false);
+ ASSERT_TRUE(connection1->version_change_transaction.is_bound());
+ connection1->version_change_transaction->CreateObjectStore(
+ kObjectStoreId, base::UTF8ToUTF16(kObjectStoreName),
+ blink::IndexedDBKeyPath(), false);
std::string value = "value";
const char* value_data = value.data();
@@ -1261,8 +1284,8 @@
::testing::InSequence dummy;
connection2 = std::make_unique<TestDatabaseConnection>(
- ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion2,
- kTransactionId2);
+ context_impl_->TaskRunner(), ToOrigin(kOrigin),
+ base::UTF8ToUTF16(kDatabaseName), kDBVersion2, kTransactionId2);
EXPECT_CALL(*connection2->open_callbacks,
MockedUpgradeNeeded(
@@ -1309,6 +1332,7 @@
connection2->database.Bind(std::move(database_info2));
ASSERT_TRUE(connection2->database.is_bound());
+ ASSERT_TRUE(connection2->version_change_transaction.is_bound());
connection2->database->Clear(
kTransactionId2, kObjectStoreId,
clear_callbacks->CreateInterfacePtrAndBind());
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 7f6b1e9..c99cd53 100644
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -42,6 +42,14 @@
namespace {
+base::FilePath CreateAndReturnTempDir(base::ScopedTempDir* temp_dir) {
+ CHECK(temp_dir->CreateUniqueTempDir());
+ return temp_dir->GetPath();
+}
+
+void CreateAndBindTransactionPlaceholder(
+ base::WeakPtr<IndexedDBTransaction> transaction) {}
+
class MockIDBFactory : public IndexedDBFactoryImpl {
public:
explicit MockIDBFactory(IndexedDBContextImpl* context)
@@ -84,14 +92,12 @@
public:
IndexedDBFactoryTest()
: quota_manager_proxy_(
- base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {}
-
- void SetUp() override {
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- context_ = base::MakeRefCounted<IndexedDBContextImpl>(
- temp_dir_.GetPath(), /*special_storage_policy=*/nullptr,
- quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
- }
+ base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)),
+ context_(base::MakeRefCounted<IndexedDBContextImpl>(
+ CreateAndReturnTempDir(&temp_dir_),
+ /*special_storage_policy=*/nullptr,
+ quota_manager_proxy_.get(),
+ indexed_db::GetDefaultLevelDBFactory())) {}
void TearDown() override {
quota_manager_proxy_->SimulateQuotaManagerDestroyed();
@@ -486,9 +492,12 @@
const Origin origin = Origin::Create(GURL("http://localhost:81"));
auto factory = base::MakeRefCounted<DiskFullFactory>(context());
const base::string16 name(ASCIIToUTF16("name"));
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
auto connection = std::make_unique<IndexedDBPendingConnection>(
callbacks, dummy_database_callbacks, /*child_process_id=*/0,
- /*transaction_id=*/2, /*version=*/1);
+ /*transaction_id=*/2, /*version=*/1,
+ std::move(create_transaction_callback));
factory->Open(name, std::move(connection), origin,
context()->data_path());
EXPECT_TRUE(callbacks->error_called());
@@ -508,9 +517,12 @@
const Origin origin = Origin::Create(GURL("http://localhost:81"));
const int64_t transaction_id = 1;
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
auto connection = std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION);
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback));
factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
context()->data_path());
@@ -539,9 +551,12 @@
const Origin origin = Origin::Create(GURL("http://localhost:81"));
const int64_t transaction_id = 1;
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
auto connection = std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION);
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback));
factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
context()->data_path());
@@ -638,9 +653,12 @@
const Origin origin = Origin::Create(GURL("http://localhost:81"));
const int64_t transaction_id = 1;
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
auto connection = std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION);
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback));
factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
context()->data_path());
@@ -733,11 +751,14 @@
base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
// Open at version 2.
const int64_t db_version = 2;
- factory->Open(db_name,
- std::make_unique<IndexedDBPendingConnection>(
- upgrade_callbacks, db_callbacks,
- /*child_process_id=*/0, transaction_id, db_version),
- origin, context()->data_path());
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
+ auto connection = std::make_unique<IndexedDBPendingConnection>(
+ upgrade_callbacks, db_callbacks,
+ /*child_process_id=*/0, transaction_id, db_version,
+ std::move(create_transaction_callback));
+ factory->Open(db_name, std::move(connection), origin,
+ context()->data_path());
EXPECT_TRUE(factory->IsDatabaseOpen(origin, db_name));
loop.Quit();
}));
@@ -762,9 +783,12 @@
// retain the database object.
{
const int64_t db_version = 1;
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
auto connection = std::make_unique<IndexedDBPendingConnection>(
failed_open_callbacks, db_callbacks2,
- /*child_process_id=*/0, transaction_id, db_version);
+ /*child_process_id=*/0, transaction_id, db_version,
+ std::move(create_transaction_callback));
factory->Open(db_name, std::move(connection), origin,
context()->data_path());
EXPECT_TRUE(failed_open_callbacks->saw_error());
@@ -835,10 +859,12 @@
callbacks = base::MakeRefCounted<DataLossCallbacks>();
auto db_callbacks =
base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
- factory->Open(ASCIIToUTF16("test_db"),
- std::make_unique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, /*child_process_id=*/0,
- transaction_id, /*version=*/1),
+ auto create_transaction_callback =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
+ auto connection = std::make_unique<IndexedDBPendingConnection>(
+ callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
+ /*version=*/1, std::move(create_transaction_callback));
+ factory->Open(ASCIIToUTF16("test_db"), std::move(connection),
origin, context()->data_path());
loop.Quit();
}));
diff --git a/content/browser/indexed_db/indexed_db_pending_connection.cc b/content/browser/indexed_db/indexed_db_pending_connection.cc
index 0f6dcea..7d2d81a3 100644
--- a/content/browser/indexed_db/indexed_db_pending_connection.cc
+++ b/content/browser/indexed_db/indexed_db_pending_connection.cc
@@ -4,6 +4,8 @@
#include "content/browser/indexed_db/indexed_db_pending_connection.h"
+#include <utility>
+
namespace content {
IndexedDBPendingConnection::IndexedDBPendingConnection(
@@ -11,15 +13,15 @@
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
int child_process_id,
int64_t transaction_id,
- int64_t version)
+ int64_t version,
+ base::OnceCallback<void(base::WeakPtr<IndexedDBTransaction>)>
+ create_transaction_callback)
: callbacks(callbacks),
database_callbacks(database_callbacks),
child_process_id(child_process_id),
transaction_id(transaction_id),
- version(version) {}
-
-IndexedDBPendingConnection::IndexedDBPendingConnection(
- const IndexedDBPendingConnection& other) = default;
+ version(version),
+ create_transaction_callback(std::move(create_transaction_callback)) {}
IndexedDBPendingConnection::~IndexedDBPendingConnection() {}
diff --git a/content/browser/indexed_db/indexed_db_pending_connection.h b/content/browser/indexed_db/indexed_db_pending_connection.h
index b434ad4..5d1b8946 100644
--- a/content/browser/indexed_db/indexed_db_pending_connection.h
+++ b/content/browser/indexed_db/indexed_db_pending_connection.h
@@ -25,8 +25,9 @@
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
int child_process_id,
int64_t transaction_id,
- int64_t version);
- IndexedDBPendingConnection(const IndexedDBPendingConnection& other);
+ int64_t version,
+ base::OnceCallback<void(base::WeakPtr<IndexedDBTransaction>)>
+ create_transaction_callback);
~IndexedDBPendingConnection();
scoped_refptr<IndexedDBCallbacks> callbacks;
scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks;
@@ -34,6 +35,8 @@
int64_t transaction_id;
int64_t version;
IndexedDBDataLossInfo data_loss_info;
+ base::OnceCallback<void(base::WeakPtr<IndexedDBTransaction>)>
+ create_transaction_callback;
};
} // namespace content
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc
index 9a81a8d..77b9706 100644
--- a/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -19,6 +19,7 @@
#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/url_constants.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "storage/browser/quota/quota_manager.h"
@@ -34,6 +35,14 @@
namespace content {
namespace {
+base::FilePath CreateAndReturnTempDir(base::ScopedTempDir* temp_dir) {
+ CHECK(temp_dir->CreateUniqueTempDir());
+ return temp_dir->GetPath();
+}
+
+void CreateAndBindTransactionPlaceholder(
+ base::WeakPtr<IndexedDBTransaction> transaction) {}
+
class LevelDBLock {
public:
LevelDBLock() : env_(nullptr), lock_(nullptr) {}
@@ -75,7 +84,12 @@
special_storage_policy_(
base::MakeRefCounted<MockSpecialStoragePolicy>()),
quota_manager_proxy_(
- base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {
+ base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)),
+ context_(base::MakeRefCounted<IndexedDBContextImpl>(
+ CreateAndReturnTempDir(&temp_dir_),
+ /*special_storage_policy=*/special_storage_policy_.get(),
+ quota_manager_proxy_.get(),
+ indexed_db::GetDefaultLevelDBFactory())) {
special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL());
}
~IndexedDBTest() override {
@@ -83,28 +97,25 @@
}
protected:
+ IndexedDBContextImpl* context() const { return context_.get(); }
scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
private:
TestBrowserThreadBundle thread_bundle_;
+ TestBrowserContext browser_context_;
+ base::ScopedTempDir temp_dir_;
+ scoped_refptr<IndexedDBContextImpl> context_;
DISALLOW_COPY_AND_ASSIGN(IndexedDBTest);
};
TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
base::FilePath normal_path;
base::FilePath session_only_path;
- auto idb_context = base::MakeRefCounted<IndexedDBContextImpl>(
- temp_dir.GetPath(), special_storage_policy_.get(),
- quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
-
- normal_path = idb_context->GetFilePathForTesting(kNormalOrigin);
- session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin);
+ normal_path = context()->GetFilePathForTesting(kNormalOrigin);
+ session_only_path = context()->GetFilePathForTesting(kSessionOnlyOrigin);
ASSERT_TRUE(base::CreateDirectory(normal_path));
ASSERT_TRUE(base::CreateDirectory(session_only_path));
RunAllTasksUntilIdle();
@@ -112,7 +123,7 @@
RunAllTasksUntilIdle();
- idb_context->Shutdown();
+ context()->Shutdown();
RunAllTasksUntilIdle();
@@ -121,28 +132,19 @@
}
TEST_F(IndexedDBTest, SetForceKeepSessionState) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
base::FilePath normal_path;
base::FilePath session_only_path;
- // Create some indexedDB paths.
- // With the levelDB backend, these are directories.
- auto idb_context = base::MakeRefCounted<IndexedDBContextImpl>(
- temp_dir.GetPath(), special_storage_policy_.get(),
- quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
-
// Save session state. This should bypass the destruction-time deletion.
- idb_context->SetForceKeepSessionState();
+ context()->SetForceKeepSessionState();
- normal_path = idb_context->GetFilePathForTesting(kNormalOrigin);
- session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin);
+ normal_path = context()->GetFilePathForTesting(kNormalOrigin);
+ session_only_path = context()->GetFilePathForTesting(kSessionOnlyOrigin);
ASSERT_TRUE(base::CreateDirectory(normal_path));
ASSERT_TRUE(base::CreateDirectory(session_only_path));
base::RunLoop().RunUntilIdle();
- idb_context->Shutdown();
+ context()->Shutdown();
base::RunLoop().RunUntilIdle();
@@ -180,52 +182,51 @@
};
TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
- auto idb_context = base::MakeRefCounted<IndexedDBContextImpl>(
- temp_dir.GetPath(), special_storage_policy_.get(),
- quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
-
const Origin kTestOrigin = Origin::Create(GURL("http://test/"));
base::RunLoop loop;
- idb_context->TaskRunner()->PostTask(
+ context()->TaskRunner()->PostTask(
FROM_HERE, base::BindLambdaForTesting([&]() {
const int child_process_id = 0;
const int64_t host_transaction_id = 0;
const int64_t version = 0;
- IndexedDBFactory* factory = idb_context->GetIDBFactory();
+ IndexedDBFactory* factory = context()->GetIDBFactory();
base::FilePath test_path =
- idb_context->GetFilePathForTesting(kTestOrigin);
+ context()->GetFilePathForTesting(kTestOrigin);
auto open_db_callbacks =
base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
auto closed_db_callbacks =
base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
- auto open_callbacks = base::MakeRefCounted<ForceCloseDBCallbacks>(
- idb_context, kTestOrigin);
- auto closed_callbacks = base::MakeRefCounted<ForceCloseDBCallbacks>(
- idb_context, kTestOrigin);
+ auto open_callbacks =
+ base::MakeRefCounted<ForceCloseDBCallbacks>(context(), kTestOrigin);
+ auto closed_callbacks =
+ base::MakeRefCounted<ForceCloseDBCallbacks>(context(), kTestOrigin);
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
factory->Open(base::ASCIIToUTF16("opendb"),
std::make_unique<IndexedDBPendingConnection>(
open_callbacks, open_db_callbacks, child_process_id,
- host_transaction_id, version),
- kTestOrigin, idb_context->data_path());
+ host_transaction_id, version,
+ std::move(create_transaction_callback1)),
+ kTestOrigin, context()->data_path());
EXPECT_TRUE(base::DirectoryExists(test_path));
+ auto create_transaction_callback2 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
factory->Open(base::ASCIIToUTF16("closeddb"),
std::make_unique<IndexedDBPendingConnection>(
closed_callbacks, closed_db_callbacks,
- child_process_id, host_transaction_id, version),
- kTestOrigin, idb_context->data_path());
+ child_process_id, host_transaction_id, version,
+ std::move(create_transaction_callback2)),
+ kTestOrigin, context()->data_path());
closed_callbacks->connection()->Close();
- idb_context->DeleteForOrigin(kTestOrigin);
+ context()->DeleteForOrigin(kTestOrigin);
EXPECT_TRUE(open_db_callbacks->forced_close_called());
EXPECT_FALSE(closed_db_callbacks->forced_close_called());
@@ -236,48 +237,33 @@
}
TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const Origin kTestOrigin = Origin::Create(GURL("http://test/"));
- auto idb_context = base::MakeRefCounted<IndexedDBContextImpl>(
- temp_dir.GetPath(), special_storage_policy_.get(),
- quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
-
- base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin);
+ base::FilePath test_path = context()->GetFilePathForTesting(kTestOrigin);
ASSERT_TRUE(base::CreateDirectory(test_path));
auto lock = LockForTesting(test_path);
ASSERT_TRUE(lock);
base::RunLoop loop;
- idb_context->TaskRunner()->PostTask(
- FROM_HERE, base::BindLambdaForTesting([&]() {
- idb_context->DeleteForOrigin(kTestOrigin);
- loop.Quit();
- }));
+ context()->TaskRunner()->PostTask(FROM_HERE,
+ base::BindLambdaForTesting([&]() {
+ context()->DeleteForOrigin(kTestOrigin);
+ loop.Quit();
+ }));
loop.Run();
EXPECT_TRUE(base::DirectoryExists(test_path));
}
TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
-
- auto idb_context = base::MakeRefCounted<IndexedDBContextImpl>(
- temp_dir.GetPath(), special_storage_policy_.get(),
- quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
-
- auto temp_path = temp_dir.GetPath();
-
base::RunLoop loop;
- idb_context->TaskRunner()->PostTask(
+ context()->TaskRunner()->PostTask(
FROM_HERE, base::BindLambdaForTesting([&]() {
const Origin kTestOrigin = Origin::Create(GURL("http://test/"));
auto* factory =
- static_cast<IndexedDBFactoryImpl*>(idb_context->GetIDBFactory());
+ static_cast<IndexedDBFactoryImpl*>(context()->GetIDBFactory());
const int child_process_id = 0;
const int64_t transaction_id = 1;
@@ -285,16 +271,19 @@
auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>();
auto db_callbacks =
base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
+ auto create_transaction_callback1 =
+ base::BindOnce(&CreateAndBindTransactionPlaceholder);
auto connection = std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, child_process_id, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION);
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION,
+ std::move(create_transaction_callback1));
factory->Open(base::ASCIIToUTF16("db"), std::move(connection),
- Origin(kTestOrigin), temp_path);
+ Origin(kTestOrigin), context()->data_path());
EXPECT_TRUE(callbacks->connection());
// ConnectionOpened() is usually called by the dispatcher.
- idb_context->ConnectionOpened(kTestOrigin, callbacks->connection());
+ context()->ConnectionOpened(kTestOrigin, callbacks->connection());
EXPECT_TRUE(factory->IsBackingStoreOpen(kTestOrigin));
diff --git a/content/browser/indexed_db/transaction_impl.cc b/content/browser/indexed_db/transaction_impl.cc
new file mode 100644
index 0000000..dd6b06ce
--- /dev/null
+++ b/content/browser/indexed_db/transaction_impl.cc
@@ -0,0 +1,52 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/indexed_db/transaction_impl.h"
+
+#include <utility>
+
+#include "content/browser/indexed_db/indexed_db_connection.h"
+#include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
+#include "content/browser/indexed_db/indexed_db_transaction.h"
+
+namespace content {
+
+TransactionImpl::TransactionImpl(
+ base::WeakPtr<IndexedDBTransaction> transaction,
+ const url::Origin& origin,
+ base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
+ scoped_refptr<base::SequencedTaskRunner> idb_runner)
+ : dispatcher_host_(dispatcher_host),
+ indexed_db_context_(dispatcher_host->context()),
+ transaction_(std::move(transaction)),
+ origin_(origin),
+ idb_runner_(std::move(idb_runner)),
+ weak_factory_(this) {
+ DCHECK(idb_runner_->RunsTasksInCurrentSequence());
+ DCHECK(dispatcher_host_);
+ DCHECK(transaction_);
+}
+
+TransactionImpl::~TransactionImpl() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void TransactionImpl::CreateObjectStore(int64_t object_store_id,
+ const base::string16& name,
+ const blink::IndexedDBKeyPath& key_path,
+ bool auto_increment) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!transaction_)
+ return;
+
+ IndexedDBConnection* connection = transaction_->connection();
+ if (!connection->IsConnected())
+ return;
+
+ connection->database()->CreateObjectStore(transaction_.get(), object_store_id,
+ name, key_path, auto_increment);
+}
+
+} // namespace content
diff --git a/content/browser/indexed_db/transaction_impl.h b/content/browser/indexed_db/transaction_impl.h
new file mode 100644
index 0000000..f5e90a6
--- /dev/null
+++ b/content/browser/indexed_db/transaction_impl.h
@@ -0,0 +1,56 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_INDEXED_DB_TRANSACTION_IMPL_H_
+#define CONTENT_BROWSER_INDEXED_DB_TRANSACTION_IMPL_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
+
+namespace base {
+class SequencedTaskRunner;
+}
+
+namespace content {
+class IndexedDBContextImpl;
+class IndexedDBDispatcherHost;
+class IndexedDBTransaction;
+
+class TransactionImpl : public blink::mojom::IDBTransaction {
+ public:
+ explicit TransactionImpl(
+ base::WeakPtr<IndexedDBTransaction> transaction,
+ const url::Origin& origin,
+ base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host,
+ scoped_refptr<base::SequencedTaskRunner> idb_runner);
+ ~TransactionImpl() override;
+
+ // blink::mojom::IDBTransaction implementation
+ void CreateObjectStore(int64_t object_store_id,
+ const base::string16& name,
+ const blink::IndexedDBKeyPath& key_path,
+ bool auto_increment) override;
+
+ private:
+ base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host_;
+ scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
+ base::WeakPtr<IndexedDBTransaction> transaction_;
+ const url::Origin origin_;
+ scoped_refptr<base::SequencedTaskRunner> idb_runner_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ base::WeakPtrFactory<TransactionImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransactionImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_INDEXED_DB_TRANSACTION_IMPL_H_