#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/services/storage/dom_storage/local_storage_impl.h"
#include <inttypes.h>
#include <algorithm>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include "base/barrier_closure.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "components/services/storage/dom_storage/async_dom_storage_database.h"
#include "components/services/storage/dom_storage/dom_storage_constants.h"
#include "components/services/storage/dom_storage/dom_storage_database.h"
#include "components/services/storage/dom_storage/features.h"
#include "components/services/storage/dom_storage/local_storage_database.pb.h"
#include "components/services/storage/dom_storage/storage_area_impl.h"
#include "components/services/storage/public/cpp/constants.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "storage/common/database/database_identifier.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
namespace storage {
namespace {
StorageAreaImpl;
static const int kDaysInTenYears = …;
constexpr std::string_view kVersionKey = …;
const uint8_t kMetaPrefix[] = …;
const uint8_t kAccessMetaPrefix[] = …;
const uint8_t kWriteMetaPrefix[] = …;
const int64_t kMinSchemaVersion = …;
const int64_t kCurrentLocalStorageSchemaVersion = …;
const int kCommitErrorThreshold = …;
#if BUILDFLAG(IS_ANDROID)
const unsigned kMaxLocalStorageAreaCount = 10;
const size_t kMaxLocalStorageCacheSize = 2 * 1024 * 1024;
#else
const unsigned kMaxLocalStorageAreaCount = …;
const size_t kMaxLocalStorageCacheSize = …;
#endif
DomStorageDatabase::Key CreateAccessMetaDataKey(
const blink::StorageKey& storage_key) { … }
DomStorageDatabase::Key CreateWriteMetaDataKey(
const blink::StorageKey& storage_key) { … }
std::optional<blink::StorageKey> ExtractStorageKeyFromWriteMetaDataKey(
const DomStorageDatabase::Key& key) { … }
std::optional<blink::StorageKey> ExtractStorageKeyFromAccessMetaDataKey(
const DomStorageDatabase::Key& key) { … }
void SuccessResponse(base::OnceClosure callback, bool success) { … }
void IgnoreStatus(base::OnceClosure callback, leveldb::Status status) { … }
DomStorageDatabase::Key MakeStorageKeyPrefix(
const blink::StorageKey& storage_key) { … }
void DeleteStorageKeys(AsyncDomStorageDatabase* database,
std::vector<blink::StorageKey> storage_keys,
base::OnceCallback<void(leveldb::Status)> callback) { … }
StorageAreaImpl::Options createOptions() { … }
}
class LocalStorageImpl::StorageAreaHolder final
: public StorageAreaImpl::Delegate { … };
LocalStorageImpl::LocalStorageImpl(
const base::FilePath& storage_root,
scoped_refptr<base::SequencedTaskRunner> task_runner,
mojo::PendingReceiver<mojom::LocalStorageControl> receiver)
: … { … }
void LocalStorageImpl::BindStorageArea(
const blink::StorageKey& storage_key,
mojo::PendingReceiver<blink::mojom::StorageArea> receiver) { … }
void LocalStorageImpl::GetUsage(GetUsageCallback callback) { … }
void LocalStorageImpl::DeleteStorage(const blink::StorageKey& storage_key,
DeleteStorageCallback callback) { … }
void LocalStorageImpl::CleanUpStorage(CleanUpStorageCallback callback) { … }
void LocalStorageImpl::Flush() { … }
void LocalStorageImpl::NeedsFlushForTesting(
NeedsFlushForTestingCallback callback) { … }
void LocalStorageImpl::FlushStorageKeyForTesting(
const blink::StorageKey& storage_key) { … }
void LocalStorageImpl::ShutDown(base::OnceClosure callback) { … }
void LocalStorageImpl::PurgeMemory() { … }
void LocalStorageImpl::ApplyPolicyUpdates(
std::vector<mojom::StoragePolicyUpdatePtr> policy_updates) { … }
void LocalStorageImpl::PurgeUnusedAreasIfNeeded() { … }
void LocalStorageImpl::ForceKeepSessionState() { … }
bool LocalStorageImpl::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) { … }
void LocalStorageImpl::SetDatabaseOpenCallbackForTesting(
base::OnceClosure callback) { … }
void LocalStorageImpl::OverrideDeleteStaleStorageAreasDelayForTesting(
const base::TimeDelta& delay) { … }
void LocalStorageImpl::ForceFakeOpenStorageAreaForTesting(
const blink::StorageKey& storage_key) { … }
LocalStorageImpl::~LocalStorageImpl() { … }
void LocalStorageImpl::RunWhenConnected(base::OnceClosure callback) { … }
void LocalStorageImpl::PurgeAllStorageAreas() { … }
void LocalStorageImpl::InitiateConnection(bool in_memory_only) { … }
void LocalStorageImpl::OnDatabaseOpened(leveldb::Status status) { … }
void LocalStorageImpl::OnGotDatabaseVersion(leveldb::Status status,
DomStorageDatabase::Value value) { … }
void LocalStorageImpl::OnConnectionFinished() { … }
void LocalStorageImpl::DeleteAndRecreateDatabase() { … }
void LocalStorageImpl::OnDBDestroyed(bool recreate_in_memory,
leveldb::Status status) { … }
LocalStorageImpl::StorageAreaHolder* LocalStorageImpl::GetOrCreateStorageArea(
const blink::StorageKey& storage_key) { … }
void LocalStorageImpl::RetrieveStorageUsage(GetUsageCallback callback) { … }
void LocalStorageImpl::OnGotWriteMetaData(
GetUsageCallback callback,
std::vector<DomStorageDatabase::KeyValuePair> data) { … }
void LocalStorageImpl::OnGotStorageUsageForShutdown(
std::vector<mojom::StorageUsageInfoPtr> usage) { … }
void LocalStorageImpl::OnStorageKeysDeleted(leveldb::Status status) { … }
void LocalStorageImpl::OnShutdownComplete() { … }
void LocalStorageImpl::GetStatistics(size_t* total_cache_size,
size_t* unused_area_count) { … }
void LocalStorageImpl::OnCommitResult(leveldb::Status status) { … }
void LocalStorageImpl::DeleteStaleStorageAreas() { … }
void LocalStorageImpl::OnGotMetaDataToDeleteStaleStorageAreas(
std::vector<DomStorageDatabase::KeyValuePair> data) { … }
}