#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/reporting/storage/storage_queue.h"
#include <algorithm>
#include <cstring>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/containers/adapters.h"
#include "base/containers/flat_set.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/hash.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/rand_util.h"
#include "base/sequence_checker.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_runner.h"
#include "base/task/thread_pool.h"
#include "base/thread_annotations.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "components/reporting/compression/compression_module.h"
#include "components/reporting/encryption/encryption_module_interface.h"
#include "components/reporting/proto/synced/record.pb.h"
#include "components/reporting/resources/resource_managed_buffer.h"
#include "components/reporting/resources/resource_manager.h"
#include "components/reporting/storage/storage_configuration.h"
#include "components/reporting/storage/storage_uploader_interface.h"
#include "components/reporting/util/file.h"
#include "components/reporting/util/refcounted_closure_list.h"
#include "components/reporting/util/reporting_errors.h"
#include "components/reporting/util/status.h"
#include "components/reporting/util/status_macros.h"
#include "components/reporting/util/statusor.h"
#include "components/reporting/util/task_runner_context.h"
#include "crypto/random.h"
#include "crypto/sha2.h"
#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
namespace reporting {
BASE_FEATURE(…);
namespace {
const base::FilePath::CharType METADATA_NAME[] = …);
constexpr size_t FRAME_SIZE = …;
size_t RoundUpToFrameSize(size_t size) { … }
struct RecordHeader { … };
}
void StorageQueue::Create(
const QueueOptions& options,
UploaderInterface::AsyncStartUploaderCb async_start_upload_cb,
scoped_refptr<EncryptionModuleInterface> encryption_module,
scoped_refptr<CompressionModule> compression_module,
base::OnceCallback<void(StatusOr<scoped_refptr<StorageQueue>>)>
completion_cb) { … }
StorageQueue::StorageQueue(
scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner,
const QueueOptions& options,
UploaderInterface::AsyncStartUploaderCb async_start_upload_cb,
scoped_refptr<EncryptionModuleInterface> encryption_module,
scoped_refptr<CompressionModule> compression_module)
: … { … }
StorageQueue::~StorageQueue() { … }
void StorageQueue::AssignDegradationQueues(
const std::vector<scoped_refptr<StorageQueue>>& degradation_queues) { … }
Status StorageQueue::Init() { … }
std::optional<std::string> StorageQueue::GetLastRecordDigest() const { … }
Status StorageQueue::SetOrConfirmGenerationId(const base::FilePath& full_name) { … }
StatusOr<int64_t> StorageQueue::GetFileSequenceIdFromPath(
const base::FilePath& file_name) { … }
StatusOr<int64_t> StorageQueue::AddDataFile(
const base::FilePath& full_name,
const base::FileEnumerator::FileInfo& file_info) { … }
Status StorageQueue::EnumerateDataFiles(
base::flat_set<base::FilePath>* used_files_set) { … }
Status StorageQueue::ScanLastFile() { … }
StatusOr<scoped_refptr<StorageQueue::SingleFile>> StorageQueue::AssignLastFile(
size_t size) { … }
StatusOr<scoped_refptr<StorageQueue::SingleFile>>
StorageQueue::OpenNewWriteableFile() { … }
Status StorageQueue::WriteHeaderAndBlock(
std::string_view data,
std::string_view current_record_digest,
scoped_refptr<StorageQueue::SingleFile> file) { … }
Status StorageQueue::WriteMetadata(std::string_view current_record_digest) { … }
Status StorageQueue::ReadMetadata(
const base::FilePath& meta_file_path,
size_t size,
int64_t sequencing_id,
base::flat_set<base::FilePath>* used_files_set) { … }
Status StorageQueue::RestoreMetadata(
base::flat_set<base::FilePath>* used_files_set) { … }
void StorageQueue::DeleteUnusedFiles(
const base::flat_set<base::FilePath>& used_files_set) const { … }
void StorageQueue::DeleteOutdatedMetadata(int64_t sequencing_id_to_keep) const { … }
class StorageQueue::ReadContext : public TaskRunnerContext<Status> { … };
class StorageQueue::WriteContext : public TaskRunnerContext<Status> { … };
void StorageQueue::Write(Record record,
base::OnceCallback<void(Status)> completion_cb) { … }
Status StorageQueue::ReserveNewRecordDiskSpace(const size_t total_size) { … }
void StorageQueue::RecordsShedding(
base::span<scoped_refptr<StorageQueue>> degradation_queues,
scoped_refptr<StorageQueue> writing_storage_queue,
const size_t space_to_recover,
base::OnceClosure resume_writing_cb,
base::OnceClosure writing_failure_cb) { … }
void StorageQueue::RecordsSheddingHelper(const size_t space_to_recover,
base::OnceClosure resume_writing_cb,
base::OnceClosure writing_failure_cb) { … }
bool StorageQueue::FilesShedding(const size_t space_to_recover) { … }
Status StorageQueue::SwitchLastFileIfNotEmpty() { … }
std::map<int64_t, scoped_refptr<StorageQueue::SingleFile>>
StorageQueue::CollectFilesForUpload(int64_t sequencing_id) const { … }
class StorageQueue::ConfirmContext : public TaskRunnerContext<Status> { … };
void StorageQueue::Confirm(SequenceInformation sequence_information,
bool force,
base::OnceCallback<void(Status)> completion_cb) { … }
Status StorageQueue::RemoveConfirmedData(int64_t sequencing_id) { … }
void StorageQueue::CheckBackUpload(Status status, int64_t next_sequencing_id) { … }
void StorageQueue::PeriodicUpload() { … }
void StorageQueue::Flush(base::OnceCallback<void(Status)> completion_cb) { … }
void StorageQueue::ReleaseAllFileInstances() { … }
void StorageQueue::RegisterCompletionCallback(base::OnceClosure callback) { … }
void StorageQueue::TestInjectErrorsForOperation(
test::ErrorInjectionHandlerType handler) { … }
StatusOr<scoped_refptr<StorageQueue::SingleFile>>
StorageQueue::SingleFile::Create(
const base::FilePath& filename,
int64_t size,
scoped_refptr<ResourceManager> memory_resource,
scoped_refptr<ResourceManager> disk_space_resource,
scoped_refptr<RefCountedClosureList> completion_closure_list) { … }
StorageQueue::SingleFile::SingleFile(
const base::FilePath& filename,
int64_t size,
scoped_refptr<ResourceManager> memory_resource,
scoped_refptr<ResourceManager> disk_space_resource,
scoped_refptr<RefCountedClosureList> completion_closure_list)
: … { … }
StorageQueue::SingleFile::~SingleFile() { … }
Status StorageQueue::SingleFile::Open(bool read_only) { … }
void StorageQueue::SingleFile::Close() { … }
void StorageQueue::SingleFile::DeleteWarnIfFailed() { … }
StatusOr<std::string_view> StorageQueue::SingleFile::Read(
uint32_t pos,
uint32_t size,
size_t max_buffer_size,
bool expect_readonly) { … }
StatusOr<uint32_t> StorageQueue::SingleFile::Append(std::string_view data) { … }
}