Commit a7dfd014 authored by Daniel Murphy's avatar Daniel Murphy Committed by Commit Bot

[IndexedDB] Removing all raw pointers and IndexedDBFactory dependencies

This patch:
* Changes most raw pointers to base::WeakPtr
* Removes the IndexedDBFactory raw pointer in IndexedDBDatabase and
  instead uses callbacks to report:
  1. If blobs are in use for a given origin, and
  2. If the blob journal has been cleaned.
* Changes the IndexedDBActiveBlobRegistry to use callbacks instead of
  the IndexedDBFactory as well, and also use callbacks for calling
  ReportUnusedBlob in IndexedDBOriginFactory. This simplifies the
  testing of that class.

There are no functional changes in this patch, and while all of those
raw pointers should be safe based on the architecture of the code, it
is much safer to store them appropriately now that we have our fancy
new pointer types.

Finally, this patch also does some naming changing in
IndexedDBActiveBlobRegistry to make that class easier to understand.

Bug: 1018741,960992
Change-Id: I6fd402c68d13870f347fe934b85e6281c396901d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1885094
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#711452}
parent c6c4ec37
......@@ -120,7 +120,7 @@ void DatabaseImpl::CreateTransaction(
transaction_id,
std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode,
new IndexedDBBackingStore::Transaction(
connection_->database()->backing_store(), durability));
connection_->database()->backing_store()->AsWeakPtr(), durability));
connection_->database()->RegisterAndScheduleTransaction(transaction);
dispatcher_host_->CreateAndBindTransactionImpl(
......
......@@ -2,11 +2,13 @@
// 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/indexed_db_active_blob_registry.h"
#include "base/bind.h"
#include "base/location.h"
#include "base/stl_util.h"
#include "base/task_runner.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_factory.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
......@@ -14,38 +16,42 @@
namespace content {
IndexedDBActiveBlobRegistry::IndexedDBActiveBlobRegistry(
IndexedDBBackingStore* backing_store)
: backing_store_(backing_store) {}
ReportOutstandingBlobsCallback report_outstanding_blobs,
ReportUnusedBlobCallback report_unused_blob)
: report_outstanding_blobs_(std::move(report_outstanding_blobs)),
report_unused_blob_(std::move(report_unused_blob)) {}
IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() {
}
IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() {}
void IndexedDBActiveBlobRegistry::AddBlobRef(int64_t database_id,
int64_t blob_key) {
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence());
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(report_outstanding_blobs_);
DCHECK(report_unused_blob_);
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
DCHECK(!base::Contains(deleted_dbs_, database_id));
bool need_ref = use_tracker_.empty();
SingleDBMap& single_db_map = use_tracker_[database_id];
auto iter = single_db_map.find(blob_key);
if (iter == single_db_map.end()) {
single_db_map[blob_key] = false;
if (need_ref) {
backing_store_->factory()->ReportOutstandingBlobs(
backing_store_->origin(), true);
}
bool outstanding_blobs_in_backing_store = !use_tracker_.empty();
SingleDBMap& blobs_in_db = use_tracker_[database_id];
auto iter = blobs_in_db.find(blob_key);
if (iter == blobs_in_db.end()) {
blobs_in_db[blob_key] = BlobState::kAlive;
if (!outstanding_blobs_in_backing_store)
report_outstanding_blobs_.Run(true);
} else {
DCHECK(!need_ref);
DCHECK(!iter->second); // You can't add a reference once it's been deleted.
DCHECK(outstanding_blobs_in_backing_store);
// You can't add a reference once it's been deleted.
DCHECK(iter->second == BlobState::kAlive);
}
}
void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id,
int64_t blob_key) {
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence());
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(report_outstanding_blobs_);
DCHECK(report_unused_blob_);
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
const auto& db_pair = use_tracker_.find(database_id);
......@@ -53,39 +59,37 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id,
NOTREACHED();
return;
}
SingleDBMap& single_db = db_pair->second;
auto blob_pair = single_db.find(blob_key);
if (blob_pair == single_db.end()) {
SingleDBMap& blobs_in_db = db_pair->second;
auto blob_in_db_it = blobs_in_db.find(blob_key);
if (blob_in_db_it == blobs_in_db.end()) {
NOTREACHED();
return;
}
bool delete_in_backend = false;
const auto& db_to_delete = deleted_dbs_.find(database_id);
bool db_marked_for_deletion = db_to_delete != deleted_dbs_.end();
bool delete_blob_in_backend = false;
const auto& deleted_database_it = deleted_dbs_.find(database_id);
bool db_marked_for_deletion = deleted_database_it != deleted_dbs_.end();
// Don't bother deleting the file if we're going to delete its whole
// database directory soon.
delete_in_backend = blob_pair->second && !db_marked_for_deletion;
single_db.erase(blob_pair);
if (single_db.empty()) {
delete_blob_in_backend =
blob_in_db_it->second == BlobState::kDeleted && !db_marked_for_deletion;
blobs_in_db.erase(blob_in_db_it);
if (blobs_in_db.empty()) {
use_tracker_.erase(db_pair);
if (db_marked_for_deletion) {
delete_in_backend = true;
delete_blob_in_backend = true;
blob_key = DatabaseMetaDataKey::kAllBlobsKey;
deleted_dbs_.erase(db_to_delete);
deleted_dbs_.erase(deleted_database_it);
}
}
if (delete_in_backend)
backing_store_->ReportBlobUnused(database_id, blob_key);
if (use_tracker_.empty()) {
backing_store_->factory()->ReportOutstandingBlobs(backing_store_->origin(),
false);
}
if (delete_blob_in_backend)
report_unused_blob_.Run(database_id, blob_key);
if (use_tracker_.empty())
report_outstanding_blobs_.Run(false);
}
bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id,
int64_t blob_key) {
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence());
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
const auto& db_pair = use_tracker_.find(database_id);
if (db_pair == use_tracker_.end())
......@@ -101,7 +105,7 @@ bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id,
if (iter == single_db.end())
return false;
iter->second = true;
iter->second = BlobState::kDeleted;
return true;
}
......@@ -113,29 +117,33 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
const base::FilePath& unused) {
task_runner->PostTask(
FROM_HERE, base::BindOnce(&IndexedDBActiveBlobRegistry::ReleaseBlobRef,
weak_ptr, database_id, blob_key));
std::move(weak_ptr), database_id, blob_key));
}
IndexedDBBlobInfo::ReleaseCallback
IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64_t database_id,
int64_t blob_key) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return base::BindRepeating(
&IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe,
scoped_refptr<base::TaskRunner>(backing_store_->task_runner()),
weak_factory_.GetWeakPtr(), database_id, blob_key);
base::SequencedTaskRunnerHandle::Get(), weak_factory_.GetWeakPtr(),
database_id, blob_key);
}
base::RepeatingClosure IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
int64_t database_id,
int64_t blob_key) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return base::BindRepeating(&IndexedDBActiveBlobRegistry::AddBlobRef,
weak_factory_.GetWeakPtr(), database_id, blob_key);
}
void IndexedDBActiveBlobRegistry::ForceShutdown() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
weak_factory_.InvalidateWeakPtrs();
use_tracker_.clear();
backing_store_ = nullptr;
report_outstanding_blobs_.Reset();
report_unused_blob_.Reset();
}
} // namespace content
......@@ -11,19 +11,32 @@
#include <set>
#include <utility>
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "content/browser/indexed_db/indexed_db_blob_info.h"
#include "content/common/content_export.h"
namespace content {
class IndexedDBBackingStore;
// Keeps track of blobs that have been sent to the renderer as database
// responses, and determines when the file should be deleted. The database entry
// that the blob files live in could be deleted in the database, but the file
// would need to stay alive while it is still used in the renderer.
// This class must be used on a single sequence, and will call the given
// callbacks back on the same sequence it is constructed on.
class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
public:
explicit IndexedDBActiveBlobRegistry(IndexedDBBackingStore* backing_store);
using ReportOutstandingBlobsCallback = base::RepeatingCallback<void(bool)>;
using ReportUnusedBlobCallback =
base::RepeatingCallback<void(int64_t /*database_id*/,
int64_t /*blob_key*/)>;
explicit IndexedDBActiveBlobRegistry(
ReportOutstandingBlobsCallback report_outstanding_blobs,
ReportUnusedBlobCallback report_unused_blob);
~IndexedDBActiveBlobRegistry();
// Most methods of this class, and the closure returned by
......@@ -31,6 +44,8 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
// runner. The exception is the closure returned by GetFinalReleaseCallback,
// which just calls ReleaseBlobRefThreadSafe.
// Marks a given blob or a while database as deleted by a transaction, and
// returns if the given blob key (or database) was previously used.
// Use DatabaseMetaDataKey::AllBlobsKey for "the whole database".
bool MarkDeletedCheckIfUsed(int64_t database_id, int64_t blob_key);
......@@ -47,11 +62,14 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
void ForceShutdown();
private:
// Maps blob_key -> IsDeleted; if the record's absent, it's not in active use
enum class BlobState { kAlive, kDeleted };
// Maps blob_key -> BlobState; if the record's absent, it's not in active use
// and we don't care if it's deleted.
typedef std::map<int64_t, bool> SingleDBMap;
typedef std::map<int64_t, BlobState> SingleDBMap;
void AddBlobRef(int64_t database_id, int64_t blob_key);
// Removes a reference to the given blob.
void ReleaseBlobRef(int64_t database_id, int64_t blob_key);
static void ReleaseBlobRefThreadSafe(
scoped_refptr<base::TaskRunner> task_runner,
......@@ -60,12 +78,13 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
int64_t blob_key,
const base::FilePath& unused);
SEQUENCE_CHECKER(sequence_checker_);
std::map<int64_t, SingleDBMap> use_tracker_;
// Databases that have been marked as deleted by MarkDeletedCheckIfUsed.
std::set<int64_t> deleted_dbs_;
// As long as we've got blobs registered in use_tracker_,
// backing_store_->factory() will keep backing_store_ alive for us. And
// backing_store_ owns us, so we'll stay alive as long as we're needed.
IndexedDBBackingStore* backing_store_;
ReportOutstandingBlobsCallback report_outstanding_blobs_;
ReportUnusedBlobCallback report_unused_blob_;
base::WeakPtrFactory<IndexedDBActiveBlobRegistry> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistry);
......
......@@ -24,7 +24,6 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/browser/indexed_db/indexed_db.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_blob_info.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/scopes/scope_lock.h"
......@@ -51,12 +50,12 @@ class FileWriterDelegate;
}
namespace content {
class IndexedDBFactory;
struct IndexedDBValue;
class IndexedDBActiveBlobRegistry;
class TransactionalLevelDBDatabase;
class TransactionalLevelDBFactory;
class TransactionalLevelDBIterator;
class TransactionalLevelDBTransaction;
struct IndexedDBValue;
namespace indexed_db_backing_store_unittest {
class IndexedDBBackingStoreTest;
......@@ -133,7 +132,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
class CONTENT_EXPORT Transaction {
public:
explicit Transaction(IndexedDBBackingStore* backing_store,
explicit Transaction(base::WeakPtr<IndexedDBBackingStore> backing_store,
blink::mojom::IDBTransactionDurability durability);
virtual ~Transaction();
......@@ -179,6 +178,8 @@ class CONTENT_EXPORT IndexedDBBackingStore {
const std::string& object_store_data_key,
IndexedDBValue* value);
base::WeakPtr<Transaction> AsWeakPtr();
// This holds a BlobEntryKey and the encoded IndexedDBBlobInfo vector stored
// under that key.
typedef std::vector<std::pair<BlobEntryKey, std::string> >
......@@ -270,10 +271,11 @@ class CONTENT_EXPORT IndexedDBBackingStore {
void PartitionBlobsToRemove(BlobJournalType* dead_blobs,
BlobJournalType* live_blobs) const;
// The raw pointer is not inherently safe, but IndexedDB destroys
// transactions & connections before destroying the backing store.
// TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992
IndexedDBBackingStore* backing_store_;
// This does NOT mean that this class can outlive the IndexedDBBackingStore.
// This is only to protect against security issues before this class is
// refactored away and this isn't necessary.
// https://crbug.com/1012918
base::WeakPtr<IndexedDBBackingStore> backing_store_;
TransactionalLevelDBFactory* const transactional_leveldb_factory_;
scoped_refptr<TransactionalLevelDBTransaction> transaction_;
std::map<std::string, std::unique_ptr<BlobChangeRecord>> blob_change_map_;
......@@ -348,8 +350,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
virtual bool LoadCurrentRow(leveldb::Status* s) = 0;
protected:
Cursor(IndexedDBBackingStore* backing_store,
Transaction* transaction,
Cursor(base::WeakPtr<Transaction> transaction,
int64_t database_id,
const CursorOptions& cursor_options);
explicit Cursor(const IndexedDBBackingStore::Cursor* other);
......@@ -361,14 +362,11 @@ class CONTENT_EXPORT IndexedDBBackingStore {
bool IsPastBounds() const;
bool HaveEnteredRange() const;
// The raw pointer is not inherently safe, but IndexedDB destroys
// transactions & connections before destroying the backing store.
// TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992
IndexedDBBackingStore* backing_store_;
// The raw pointer is not inherently safe, but IndexedDB destroys
// transactions before cursors.
// TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992
Transaction* transaction_;
// This does NOT mean that this class can outlive the Transaction.
// This is only to protect against security issues before this class is
// refactored away and this isn't necessary.
// https://crbug.com/1012918
base::WeakPtr<Transaction> transaction_;
int64_t database_id_;
const CursorOptions cursor_options_;
std::unique_ptr<TransactionalLevelDBIterator> iterator_;
......@@ -391,9 +389,15 @@ class CONTENT_EXPORT IndexedDBBackingStore {
IteratorState state,
leveldb::Status*);
base::WeakPtrFactory<Cursor> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(Cursor);
};
using BlobFilesCleanedCallback = base::RepeatingClosure;
using ReportOutstandingBlobsCallback =
base::RepeatingCallback<void(/*outstanding_blobs=*/bool)>;
enum class Mode { kInMemory, kOnDisk };
// Schedule an immediate blob journal cleanup if we reach this number of
......@@ -409,11 +413,12 @@ class CONTENT_EXPORT IndexedDBBackingStore {
IndexedDBBackingStore(
Mode backing_store_mode,
IndexedDBFactory* indexed_db_factory,
TransactionalLevelDBFactory* transactional_leveldb_factory,
const url::Origin& origin,
const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db,
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner);
virtual ~IndexedDBBackingStore();
......@@ -422,10 +427,9 @@ class CONTENT_EXPORT IndexedDBBackingStore {
leveldb::Status Initialize(bool clean_live_blob_journal);
const url::Origin& origin() const { return origin_; }
IndexedDBFactory* factory() const { return indexed_db_factory_; }
base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
IndexedDBActiveBlobRegistry* active_blob_registry() {
return &active_blob_registry_;
return active_blob_registry_.get();
}
void GrantChildProcessPermissions(int child_process_id);
......@@ -650,7 +654,6 @@ class CONTENT_EXPORT IndexedDBBackingStore {
void DidCommitTransaction();
Mode backing_store_mode_;
IndexedDBFactory* indexed_db_factory_;
TransactionalLevelDBFactory* const transactional_leveldb_factory_;
const url::Origin origin_;
base::FilePath blob_path_;
......@@ -677,9 +680,12 @@ class CONTENT_EXPORT IndexedDBBackingStore {
#endif
std::unique_ptr<TransactionalLevelDBDatabase> db_;
BlobFilesCleanedCallback blob_files_cleaned_;
// Whenever blobs are registered in active_blob_registry_,
// indexed_db_factory_ will hold a reference to this backing store.
IndexedDBActiveBlobRegistry active_blob_registry_;
std::unique_ptr<IndexedDBActiveBlobRegistry> active_blob_registry_;
// Incremented whenever a transaction starts committing, decremented when
// complete. While > 0, temporary journal entries may exist so out-of-band
......
......@@ -44,13 +44,15 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
auto task_runner = base::SequencedTaskRunnerHandle::Get();
std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique<
IndexedDBBackingStore>(
IndexedDBBackingStore::Mode::kInMemory, nullptr,
&transactional_leveldb_factory, origin, path,
IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory,
origin, path,
transactional_leveldb_factory.CreateLevelDBDatabase(
FakeLevelDBFactory::GetBrokenLevelDB(
leveldb::Status::IOError("It's broken!"), path),
nullptr, task_runner.get(),
TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase),
IndexedDBBackingStore::BlobFilesCleanedCallback(),
IndexedDBBackingStore::ReportOutstandingBlobsCallback(),
task_runner.get());
leveldb::Status s = backing_store->Initialize(false);
EXPECT_FALSE(s.ok());
......@@ -79,12 +81,14 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
for (leveldb::Status error_status : errors) {
std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique<
IndexedDBBackingStore>(
IndexedDBBackingStore::Mode::kInMemory, nullptr,
&transactional_leveldb_factory, origin, path,
IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory,
origin, path,
transactional_leveldb_factory.CreateLevelDBDatabase(
FakeLevelDBFactory::GetBrokenLevelDB(error_status, path), nullptr,
task_runner.get(),
TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase),
IndexedDBBackingStore::BlobFilesCleanedCallback(),
IndexedDBBackingStore::ReportOutstandingBlobsCallback(),
task_runner.get());
leveldb::Status s = backing_store->Initialize(false);
ASSERT_TRUE(s.IsIOError());
......
......@@ -188,7 +188,7 @@ TEST_F(IndexedDBDatabaseTest, ForcedClose) {
transaction_id, std::set<int64_t>(scope.begin(), scope.end()),
blink::mojom::IDBTransactionMode::ReadOnly,
new IndexedDBBackingStore::Transaction(
backing_store_.get(),
backing_store_->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed));
db_->RegisterAndScheduleTransaction(transaction);
......
......@@ -778,10 +778,14 @@ std::unique_ptr<IndexedDBBackingStore> IndexedDBFactoryImpl::CreateBackingStore(
const url::Origin& origin,
const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db,
IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned,
IndexedDBBackingStore::ReportOutstandingBlobsCallback
report_outstanding_blobs,
base::SequencedTaskRunner* task_runner) {
return std::make_unique<IndexedDBBackingStore>(
backing_store_mode, this, transactional_leveldb_factory, origin,
blob_path, std::move(db), task_runner);
backing_store_mode, transactional_leveldb_factory, origin, blob_path,
std::move(db), std::move(blob_files_cleaned),
std::move(report_outstanding_blobs), task_runner);
}
std::tuple<std::unique_ptr<IndexedDBBackingStore>,
......@@ -908,7 +912,12 @@ IndexedDBFactoryImpl::OpenAndVerifyIndexedDBBackingStore(
: IndexedDBBackingStore::Mode::kOnDisk;
std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore(
backing_store_mode, &class_factory_->transactional_leveldb_factory(),
origin, blob_path, std::move(database), context_->TaskRunner());
origin, blob_path, std::move(database),
base::BindRepeating(&IndexedDBFactoryImpl::BlobFilesCleaned,
weak_factory_.GetWeakPtr(), origin),
base::BindRepeating(&IndexedDBFactoryImpl::ReportOutstandingBlobs,
weak_factory_.GetWeakPtr(), origin),
context_->TaskRunner());
status = backing_store->Initialize(
/*cleanup_live_journal=*/(!is_incognito_and_in_memory &&
first_open_since_startup));
......
......@@ -146,6 +146,9 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
const url::Origin& origin,
const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db,
IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned,
IndexedDBBackingStore::ReportOutstandingBlobsCallback
report_outstanding_blobs,
base::SequencedTaskRunner* task_runner);
IndexedDBContextImpl* context() const { return context_; }
......@@ -205,6 +208,7 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
bool IsBackingStorePendingClose(const url::Origin& origin) const;
SEQUENCE_CHECKER(sequence_checker_);
// Raw pointer is safe because IndexedDBContextImpl owns this object.
IndexedDBContextImpl* context_;
IndexedDBClassFactory* const class_factory_;
base::Clock* const clock_;
......
......@@ -28,21 +28,24 @@ TransactionalLevelDBFactory* GetTransactionalLevelDBFactory() {
IndexedDBFakeBackingStore::IndexedDBFakeBackingStore()
: IndexedDBBackingStore(IndexedDBBackingStore::Mode::kInMemory,
nullptr /* indexed_db_factory */,
GetTransactionalLevelDBFactory(),
url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(),
std::unique_ptr<TransactionalLevelDBDatabase>(),
BlobFilesCleanedCallback(),
ReportOutstandingBlobsCallback(),
base::SequencedTaskRunnerHandle::Get().get()) {}
IndexedDBFakeBackingStore::IndexedDBFakeBackingStore(
IndexedDBFactory* factory,
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner)
: IndexedDBBackingStore(IndexedDBBackingStore::Mode::kOnDisk,
factory,
GetTransactionalLevelDBFactory(),
url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(),
std::unique_ptr<TransactionalLevelDBDatabase>(),
std::move(blob_files_cleaned),
std::move(report_outstanding_blobs),
task_runner) {}
IndexedDBFakeBackingStore::~IndexedDBFakeBackingStore() {}
......
......@@ -24,13 +24,13 @@ class IndexedDBKeyRange;
namespace content {
class IndexedDBFactory;
class IndexedDBFakeBackingStore : public IndexedDBBackingStore {
public:
IndexedDBFakeBackingStore();
IndexedDBFakeBackingStore(IndexedDBFactory* factory,
base::SequencedTaskRunner* task_runner);
IndexedDBFakeBackingStore(
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner);
~IndexedDBFakeBackingStore() override;
leveldb::Status DeleteDatabase(
......
......@@ -12,6 +12,7 @@
#include "base/feature_list.h"
#include "base/rand_util.h"
#include "base/stl_util.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment