chromium/content/browser/indexed_db/indexed_db_bucket_context.cc

// Copyright 2019 The Chromium Authors
// 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_bucket_context.h"

#include <inttypes.h>
#include <stddef.h>

#include <algorithm>
#include <atomic>
#include <compare>
#include <list>
#include <ostream>
#include <set>
#include <type_traits>
#include <utility>
#include <vector>

#include "base/check.h"
#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/containers/contains.h"
#include "base/containers/map_util.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/rand_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/system/sys_info.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/common/trace_event_common.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/uuid.h"
#include "build/build_config.h"
#include "components/services/storage/indexed_db/leveldb/leveldb_state.h"
#include "components/services/storage/indexed_db/locks/partitioned_lock_manager.h"
#include "components/services/storage/indexed_db/scopes/leveldb_scopes.h"
#include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h"
#include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h"
#include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_transaction.h"
#include "components/services/storage/privileged/mojom/indexed_db_client_state_checker.mojom.h"
#include "components/services/storage/privileged/mojom/indexed_db_internals_types.mojom-forward.h"
#include "components/services/storage/privileged/mojom/indexed_db_internals_types.mojom-shared.h"
#include "components/services/storage/privileged/mojom/indexed_db_internals_types.mojom.h"
#include "components/services/storage/public/mojom/blob_storage_context.mojom-shared.h"
#include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
#include "content/browser/indexed_db/file_path_util.h"
#include "content/browser/indexed_db/file_stream_reader_to_data_pipe.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_bucket_context_handle.h"
#include "content/browser/indexed_db/indexed_db_compaction_task.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
#include "content/browser/indexed_db/indexed_db_data_format_version.h"
#include "content/browser/indexed_db/indexed_db_data_loss_info.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_database_error.h"
#include "content/browser/indexed_db/indexed_db_external_object.h"
#include "content/browser/indexed_db/indexed_db_factory_client.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/indexed_db_leveldb_operations.h"
#include "content/browser/indexed_db/indexed_db_pending_connection.h"
#include "content/browser/indexed_db/indexed_db_pre_close_task_queue.h"
#include "content/browser/indexed_db/indexed_db_reporting.h"
#include "content/browser/indexed_db/indexed_db_tombstone_sweeper.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/list_set.h"
#include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
#include "content/public/common/content_features.h"
#include "env_chromium.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/net_errors.h"
#include "storage/browser/file_system/file_stream_reader.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_metadata.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/file_system_access/file_system_access_transfer_token.mojom.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-shared.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
#include "third_party/leveldatabase/leveldb_chrome.h"

namespace content {
namespace {
// Time after the last connection to a database is closed and when we destroy
// the backing store.
const int64_t kBackingStoreGracePeriodSeconds =;
// Total time we let pre-close tasks run.
const int64_t kRunningPreCloseTasksMaxRunPeriodSeconds =;
// The number of iterations for every 'round' of the tombstone sweeper.
const int kTombstoneSweeperRoundIterations =;
// The maximum total iterations for the tombstone sweeper.
const int kTombstoneSweeperMaxIterations =;

constexpr const base::TimeDelta kMinEarliestBucketSweepFromNow =;
static_assert;

constexpr const base::TimeDelta kMinEarliestGlobalSweepFromNow =;
static_assert;

base::Time GenerateNextBucketSweepTime(base::Time now) {}

base::Time GenerateNextGlobalSweepTime(base::Time now) {}

constexpr const base::TimeDelta kMinEarliestBucketCompactionFromNow =;
static_assert;

constexpr const base::TimeDelta kMinEarliestGlobalCompactionFromNow =;
static_assert;

base::Time GenerateNextBucketCompactionTime(base::Time now) {}

base::Time GenerateNextGlobalCompactionTime(base::Time now) {}

// This struct facilitates requesting bucket space usage from the quota manager.
// There have been reports of the callback being passed to the quota manager
// never being invoked. This struct will make sure to invoke the wrapped
// callback when it goes out of scope. The struct itself is in turn intended to
// be wrapped in a callback passed to the quota manager.
//
// There are three main tasks for this struct.
// * It makes sure the passed callback is run by doing so on destruction.
// * It logs UMA.
// * It times out the request if the quota manager is taking too long.
struct GetBucketSpaceRequestWrapper {};

IndexedDBDatabaseError CreateDefaultError() {}

// Returns some configuration that is shared across leveldb DB instances. The
// configuration is further tweaked in `CreateLevelDBState()`.
leveldb_env::Options GetLevelDBOptions() {}

std::tuple<scoped_refptr<LevelDBState>,
           leveldb::Status,
           /* is_disk_full= */ bool>
CreateLevelDBState(const leveldb_env::Options& base_options,
                   const base::FilePath& file_name,
                   bool create_if_missing,
                   const std::string& in_memory_name) {}

// Creates the leveldb and blob storage directories for IndexedDB.
std::tuple<base::FilePath /*leveldb_path*/,
           base::FilePath /*blob_path*/,
           leveldb::Status>
CreateDatabaseDirectories(const base::FilePath& path_base,
                          const storage::BucketLocator& bucket_locator) {}

std::tuple<bool, leveldb::Status> AreSchemasKnown(
    TransactionalLevelDBDatabase* db) {}

}  // namespace

// BlobDataItemReader implementation providing a BlobDataItem -> file adapter.
class IndexedDBDataItemReader : public storage::mojom::BlobDataItemReader {};

constexpr const base::TimeDelta
    IndexedDBBucketContext::kMaxEarliestGlobalSweepFromNow;
constexpr const base::TimeDelta
    IndexedDBBucketContext::kMaxEarliestBucketSweepFromNow;

constexpr const base::TimeDelta
    IndexedDBBucketContext::kMaxEarliestGlobalCompactionFromNow;
constexpr const base::TimeDelta
    IndexedDBBucketContext::kMaxEarliestBucketCompactionFromNow;

IndexedDBBucketContext::Delegate::Delegate()
    :{}

IndexedDBBucketContext::Delegate::Delegate(Delegate&& other) = default;
IndexedDBBucketContext::Delegate::~Delegate() = default;

IndexedDBBucketContext::IndexedDBBucketContext(
    storage::BucketInfo bucket_info,
    const base::FilePath& data_path,
    Delegate&& delegate,
    scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
    scoped_refptr<base::TaskRunner> io_task_runner,
    mojo::PendingRemote<storage::mojom::BlobStorageContext>
        blob_storage_context,
    mojo::PendingRemote<storage::mojom::FileSystemAccessContext>
        file_system_access_context,
    InstanceClosure initialize_closure)
    :{}

IndexedDBBucketContext::~IndexedDBBucketContext() {}

void IndexedDBBucketContext::ForceClose(bool doom) {}

void IndexedDBBucketContext::StartMetadataRecording() {}

std::vector<storage::mojom::IdbBucketMetadataPtr>
IndexedDBBucketContext::StopMetadataRecording() {}

int64_t IndexedDBBucketContext::GetInMemorySize() {}

void IndexedDBBucketContext::ReportOutstandingBlobs(bool blobs_outstanding) {}

void IndexedDBBucketContext::RunInstanceClosure(InstanceClosure method) {}

void IndexedDBBucketContext::CheckCanUseDiskSpace(
    int64_t space_requested,
    base::OnceCallback<void(bool)> bucket_space_check_callback) {}

void IndexedDBBucketContext::OnGotBucketSpaceRemaining(
    storage::QuotaErrorOr<int64_t> space_left) {}

int64_t IndexedDBBucketContext::GetBucketSpaceToAllot() {}

void IndexedDBBucketContext::CreateAllExternalObjects(
    const std::vector<IndexedDBExternalObject>& objects,
    std::vector<blink::mojom::IDBExternalObjectPtr>* mojo_objects) {}

void IndexedDBBucketContext::QueueRunTasks() {}

void IndexedDBBucketContext::RunTasks() {}

void IndexedDBBucketContext::AddReceiver(
    const storage::BucketClientInfo& client_info,
    mojo::PendingRemote<storage::mojom::IndexedDBClientStateChecker>
        client_state_checker_remote,
    mojo::PendingReceiver<blink::mojom::IDBFactory> pending_receiver) {}

void IndexedDBBucketContext::GetDatabaseInfo(GetDatabaseInfoCallback callback) {}

void IndexedDBBucketContext::Open(
    mojo::PendingAssociatedRemote<blink::mojom::IDBFactoryClient>
        factory_client,
    mojo::PendingAssociatedRemote<blink::mojom::IDBDatabaseCallbacks>
        database_callbacks_remote,
    const std::u16string& name,
    int64_t version,
    mojo::PendingAssociatedReceiver<blink::mojom::IDBTransaction>
        transaction_receiver,
    int64_t transaction_id) {}

void IndexedDBBucketContext::DeleteDatabase(
    mojo::PendingAssociatedRemote<blink::mojom::IDBFactoryClient>
        factory_client,
    const std::u16string& name,
    bool force_close) {}

storage::mojom::IdbBucketMetadataPtr IndexedDBBucketContext::FillInMetadata(
    storage::mojom::IdbBucketMetadataPtr info) {}

void IndexedDBBucketContext::NotifyOfIdbInternalsRelevantChange() {}

IndexedDBBucketContext* IndexedDBBucketContext::GetReferenceForTesting() {}

void IndexedDBBucketContext::CompactBackingStoreForTesting() {}

void IndexedDBBucketContext::WriteToIndexedDBForTesting(
    const std::string& key,
    const std::string& value) {}

void IndexedDBBucketContext::BindMockFailureSingletonForTesting(
    mojo::PendingReceiver<storage::mojom::MockFailureInjector> receiver) {}

// static
void IndexedDBBucketContext::SetInternalState(
    base::Time earliest_global_sweep_time,
    base::Time earliest_global_compaction_time,
    IndexedDBBucketContext& context) {}

IndexedDBDatabase* IndexedDBBucketContext::AddDatabase(
    const std::u16string& name,
    std::unique_ptr<IndexedDBDatabase> database) {}

void IndexedDBBucketContext::OnHandleCreated() {}

void IndexedDBBucketContext::OnHandleDestruction() {}

bool IndexedDBBucketContext::CanClose() {}

void IndexedDBBucketContext::MaybeStartClosing() {}

void IndexedDBBucketContext::StartClosing() {}

void IndexedDBBucketContext::StartPreCloseTasks() {}

void IndexedDBBucketContext::CloseNow() {}

bool IndexedDBBucketContext::ShouldRunTombstoneSweeper() {}

bool IndexedDBBucketContext::ShouldRunCompaction() {}

void IndexedDBBucketContext::BindFileReader(
    const base::FilePath& path,
    base::Time expected_modification_time,
    base::OnceClosure release_callback,
    mojo::PendingReceiver<storage::mojom::BlobDataItemReader> receiver) {}

void IndexedDBBucketContext::RemoveBoundReaders(const base::FilePath& path) {}

void IndexedDBBucketContext::HandleBackingStoreCorruption(
    const IndexedDBDatabaseError& error) {}

void IndexedDBBucketContext::OnDatabaseError(leveldb::Status status,
                                             const std::string& message) {}

bool IndexedDBBucketContext::OnMemoryDump(
    const base::trace_event::MemoryDumpArgs& args,
    base::trace_event::ProcessMemoryDump* pmd) {}

std::tuple<std::unique_ptr<IndexedDBBackingStore>,
           leveldb::Status,
           IndexedDBDataLossInfo,
           bool /* is_disk_full */>
IndexedDBBucketContext::OpenAndVerifyIndexedDBBackingStore(
    base::FilePath data_directory,
    base::FilePath database_path,
    base::FilePath blob_path,
    PartitionedLockManager* lock_manager,
    bool is_first_attempt,
    bool create_if_missing) {}

std::tuple<leveldb::Status, IndexedDBDatabaseError, IndexedDBDataLossInfo>
IndexedDBBucketContext::InitBackingStoreIfNeeded(bool create_if_missing) {}

void IndexedDBBucketContext::ResetBackingStore() {}

void IndexedDBBucketContext::OnReceiverDisconnected() {}

void IndexedDBBucketContext::RecordInternalsSnapshot() {}

IndexedDBBucketContext::ReceiverContext::ReceiverContext(
    const storage::BucketClientInfo& client_info,
    mojo::PendingRemote<storage::mojom::IndexedDBClientStateChecker>
        client_state_checker_remote)
    :{}

IndexedDBBucketContext::ReceiverContext::ReceiverContext(
    IndexedDBBucketContext::ReceiverContext&&) noexcept = default;
IndexedDBBucketContext::ReceiverContext::~ReceiverContext() = default;

}  // namespace content