chromium/content/browser/interest_group/interest_group_storage.cc

// Copyright 2021 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/interest_group/interest_group_storage.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/json/json_string_value_serializer.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/sequence_checker.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/trace_event/typed_macros.h"
#include "base/types/pass_key.h"
#include "content/browser/interest_group/bidding_and_auction_server_key_fetcher.h"
#include "content/browser/interest_group/for_debugging_only_report_util.h"
#include "content/browser/interest_group/interest_group_features.h"
#include "content/browser/interest_group/interest_group_k_anonymity_manager.h"
#include "content/browser/interest_group/interest_group_storage.pb.h"
#include "content/browser/interest_group/interest_group_update.h"
#include "content/browser/interest_group/storage_interest_group.h"
#include "content/services/auction_worklet/public/mojom/bidder_worklet.mojom.h"
#include "crypto/sha2.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "sql/database.h"
#include "sql/error_delegate_util.h"
#include "sql/meta_table.h"
#include "sql/recovery.h"
#include "sql/statement.h"
#include "sql/transaction.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/interest_group/interest_group.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/boringssl/src/include/openssl/curve25519.h"
#include "third_party/snappy/src/snappy.h"
#include "third_party/sqlite/sqlite3.h"
#include "url/origin.h"

namespace content {

namespace {

PassKey;
BiddingBrowserSignalsPtr;
PreviousWinPtr;
SellerCapabilitiesType;

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(AdProtoDecompressionOutcome)
enum class AdProtoDecompressionOutcome {};

// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:AdProtoDecompressionOutcome)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InterestGroupStorageInitializationResult)
enum class InterestGroupStorageInitializationResult {};
// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:InterestGroupStorageInitializationResult)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InterestGroupStorageJSONDeserializationResult)
enum class InterestGroupStorageJSONDeserializationResult {};
// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:InterestGroupStorageJSONDeserializationResult)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InterestGroupStorageJSONSerializationResult)
enum class InterestGroupStorageJSONSerializationResult {};
// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:InterestGroupStorageJSONSerializationResult)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InterestGroupStorageProtoDeserializationResult)
enum class InterestGroupStorageProtoDeserializationResult {};
// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:InterestGroupStorageProtoDeserializationResult)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InterestGroupStorageProtoSerializationResult)
enum class InterestGroupStorageProtoSerializationResult {};
// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:InterestGroupStorageProtoSerializationResult)

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(InterestGroupStorageVacuumResult)
enum class InterestGroupStorageVacuumResult {};
// LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:InterestGroupStorageVacuumResult)

const base::FilePath::CharType kDatabasePath[] =);

// Version number of the database.
//
// Version 1 - 2021/03 - crrev.com/c/2757425
// Version 2 - 2021/08 - crrev.com/c/3097715
// Version 3 - 2021/09 - crrev.com/c/3165576
// Version 4 - 2021/10 - crrev.com/c/3172863
// Version 5 - 2021/10 - crrev.com/c/3067804
// Version 6 - 2021/12 - crrev.com/c/3330516
// Version 7 - 2022/03 - crrev.com/c/3517534
// Version 8 - 2022/06 - crrev.com/c/3696265
// Version 9 - 2022/07 - crrev.com/c/3780305
// Version 10 - 2022/08 - crrev.com/c/3818142
// Version 13 - 2023/01 - crrev.com/c/4167800
// Version 14 - 2023/08 - crrev.com/c/4739632
// Version 15 - 2023/08 - crrev.com/c/4808727
// Version 16 - 2023/08 - crrev.com/c/4822944
// Version 17 - 2023/09 - crrev.com/c/4852051
// Version 18 - 2023/09 - crrev.com/c/4902233
// Version 19 - 2023/10 - crrev.com/c/4891458
// Version 20 - 2023/11 - crrev.com/c/5050989
// Version 21 - 2023/11 - crrev.com/c/5063314
// Version 22 - 2023/12 - crrev.com/c/5063589
// Version 23 - 2024/01 - crrev.com/c/5173733
// Version 24 - 2024/01 - crrev.com/c/5245196
// Version 25 - 2024/04 - crrev.com/c/5497898
// Version 26 - 2024/05 - crrev.com/c/5555460
// Version 27 - 2024/05 - crrev.com/c/5521957
// Version 28 - 2024/06 - crrev.com/c/5647523
// Version 29 - 2024/06 - crrev.com/c/5753049
// Version 30 - 2024/08 - crrev.com/c/5707491
//
// Version 1 adds a table for interest groups.
// Version 2 adds a column for rate limiting interest group updates.
// Version 3 adds a field for ad components.
// Version 4 adds joining origin and url.
// Version 5 adds k-anonymity tables and fields.
// Version 6 adds WebAssembly helper url.
// Version 7 changes an index, adds interest group priority.
// Version 8 adds the execution_mode field to interest groups.
// Version 9 changes bid_history and join_history to daily counts.
// Version 10 changes k-anonymity table so it doesn't split by type.
// Version 11 adds priority vector support and time a group was joined.
// Version 12 adds seller capabilities fields.
// Version 13 adds ad size-related fields (ad_sizes & size_groups).
// Version 14 adds auction server request flags.
// Version 15 adds an additional bid key field.
// Version 16 changes the ads and ad component columns of the interest group
// table to protobuf format.
// Version 17 adds interest group name and owner columns to the k-anonymity
// table.
// Version 18 adds a new index on IG type (regular vs negative) to support
// split caps on max interest groups per owner.
// Version 19 adds the aggregation_coordinator_origin and storage_size columns
// to the interest group table.
// Version 20 adds the lockout_debugging_only_report and
// cooldown_debugging_only_report tables.
// Version 21 adds the trusted_bidding_signals_slot_size_mode column to the
// interest group table.
// Version 22 adds id column to the debug report lockout table, and changes
// starting and duration columns to starting_time and type columns to the debug
// report cooldown table.
// Version 23 adds trusted bidding signals URL length limit.
// Version 24 adds cached B&A server keys.
// Version 25 uses hashed k-anon keys instead of the unhashed versions.
// Version 26 runs a VACUUM command.
// Version 27 stores k-anon values and update times in interest group table.
// Version 28 adds trusted bidding signals coordinator.
// Version 29 adds selectableBuyerAndSellerReportingIds field to ad object.
// Version 30 compresses the AdsProto field using Snappy compression and runs a
// VACUUM command.

const int kCurrentVersionNumber =;

// Earliest version of the code which can use a |kCurrentVersionNumber| database
// without failing.
const int kCompatibleVersionNumber =;

// Latest version of the database that cannot be upgraded to
// |kCurrentVersionNumber| without razing the database.
const int kDeprecatedVersionNumber =;

std::string Serialize(base::ValueView value_view) {}
std::unique_ptr<base::Value> DeserializeValue(
    const std::string& serialized_value) {}

std::string Serialize(const url::Origin& origin) {}
url::Origin DeserializeOrigin(const std::string& serialized_origin) {}

std::string Serialize(const std::optional<GURL>& url) {}
std::optional<GURL> DeserializeURL(const std::string& serialized_url) {}

blink::InterestGroup::Ad FromInterestGroupAdValue(const PassKey& passkey,
                                                  const base::Value::Dict& dict,
                                                  bool for_components) {}

std::string Serialize(
    const std::optional<base::flat_map<std::string, double>>& flat_map) {}
std::optional<base::flat_map<std::string, double>> DeserializeStringDoubleMap(
    const std::string& serialized_flat_map) {}

AdProtos GetAdProtosFromAds(std::vector<blink::InterestGroup::Ad> ads) {}

// Upgrade code needs to serialize without compression -- otherwise, the
// Serialize() method below is used.
std::string SerializeUncompressed(
    const std::optional<std::vector<blink::InterestGroup::Ad>>& ads) {}

std::string Serialize(
    const std::optional<std::vector<blink::InterestGroup::Ad>>& ads) {}

std::optional<std::vector<blink::InterestGroup::Ad>>
DeserializeInterestGroupAdVectorJson(const PassKey& passkey,
                                     const std::string& serialized_ads,
                                     bool for_components) {}

// Upgrade code needs to deserialize without decompression -- otherwise,
// DecompressAndDeserializeInterestGroupAdVectorProto() is used.
std::optional<std::vector<blink::InterestGroup::Ad>>
DeserializeInterestGroupAdVectorProto(const PassKey& passkey,
                                      const std::string& serialized_ads) {}

std::optional<std::vector<blink::InterestGroup::Ad>>
DecompressAndDeserializeInterestGroupAdVectorProto(
    const PassKey& passkey,
    const std::string& compressed) {}

std::string Serialize(
    const std::optional<base::flat_map<std::string, blink::AdSize>>& ad_sizes) {}
std::optional<base::flat_map<std::string, blink::AdSize>>
DeserializeStringSizeMap(const std::string& serialized_sizes) {}

std::string Serialize(
    const std::optional<base::flat_map<std::string, std::vector<std::string>>>&
        size_groups) {}
std::optional<base::flat_map<std::string, std::vector<std::string>>>
DeserializeStringStringVectorMap(const std::string& serialized_groups) {}

std::string Serialize(const std::optional<std::vector<std::string>>& strings) {}

std::optional<std::vector<std::string>> DeserializeStringVector(
    const std::string& serialized_vector) {}

int64_t Serialize(SellerCapabilitiesType capabilities) {}
SellerCapabilitiesType DeserializeSellerCapabilities(int64_t serialized) {}

std::string Serialize(
    const std::optional<base::flat_map<url::Origin, SellerCapabilitiesType>>&
        flat_map) {}
std::optional<base::flat_map<url::Origin, SellerCapabilitiesType>>
DeserializeSellerCapabilitiesMap(const std::string& serialized) {}

int64_t Serialize(blink::AuctionServerRequestFlags flags) {}
blink::AuctionServerRequestFlags DeserializeAuctionServerRequestFlags(
    int64_t serialized) {}

std::vector<uint8_t> Serialize(
    std::optional<blink::InterestGroup::AdditionalBidKey> key) {}
std::optional<blink::InterestGroup::AdditionalBidKey>
DeserializeAdditionalBidKey(const base::span<const uint8_t>& serialized) {}

// Merges new `priority_signals_overrides` received from an update with an
// existing set of overrides store with an interest group. Populates `overrides`
// if it was previously null.
void MergePrioritySignalsOverrides(
    const base::flat_map<std::string, std::optional<double>>& update_data,
    std::optional<base::flat_map<std::string, double>>&
        priority_signals_overrides) {}

// Same as above, but takes a map with PrioritySignalsDoublePtrs instead of
// std::optional<double>s. This isn't much more code than it takes to convert
// the flat_map of PrioritySignalsDoublePtr to one of optionals, so just
// duplicate the logic.
void MergePrioritySignalsOverrides(
    const base::flat_map<std::string,
                         auction_worklet::mojom::PrioritySignalsDoublePtr>&
        update_data,
    std::optional<base::flat_map<std::string, double>>&
        priority_signals_overrides) {}

// These values are persisted to the database. Do not change.
enum KAnonKeyType {};

KAnonKeyType GetKAnonType(const std::string& unhashed_key) {}

std::set<std::string> GetAllKanonKeys(
    const blink::InterestGroup& interest_group) {}

// Adds indices to the `interest_group` table.
// Call this function after the table has been created,
// both when creating a new database in CreateVxxSchema
// and after dropping/recreating the `interest_groups` table
// in the *latest* UpgradeVxxSchemaToVxx function to do so.
bool CreateInterestGroupIndices(sql::Database& db) {}

// Adds indices to the `kanon` table.
// Call this function after the table has been created,
// both when creating a new database in CreateVxxSchema
// and after dropping/recreating the `kanon` table
// in the *latest* UpgradeVxxSchemaToVxx function to do so.
bool CreateKAnonIndices(sql::Database& db) {}

bool MaybeCreateKAnonEntryForV17DatabaseUpgrade(
    sql::Database& db,
    const blink::InterestGroupKey& interest_group_key,
    const std::string& key,
    const base::Time& now) {}

// Initializes the tables, returning true on success.
// The tables cannot exist when calling this function.
bool CreateV29Schema(sql::Database& db) {}

bool VacuumDB(sql::Database& db) {}

bool UpgradeV29SchemaToV30(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV27SchemaToV28(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV26SchemaToV27(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV24SchemaToV25(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV23SchemaToV24(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV22SchemaToV23(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV21SchemaToV22(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV20SchemaToV21(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV19SchemaToV20(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV18SchemaToV19(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV17SchemaToV18(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV16SchemaToV17(sql::Database& db,
                           sql::MetaTable& meta_table,
                           const PassKey& passkey) {}

bool UpgradeV15SchemaToV16(sql::Database& db,
                           sql::MetaTable& meta_table,
                           const PassKey& passkey) {}

bool UpgradeV14SchemaToV15(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV13SchemaToV14(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV12SchemaToV13(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV11SchemaToV12(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV10SchemaToV11(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV9SchemaToV10(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV8SchemaToV9(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV7SchemaToV8(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeV6SchemaToV7(sql::Database& db, sql::MetaTable& meta_table) {}

bool UpgradeDB(sql::Database& db,
               const int db_version,
               sql::MetaTable& meta_table,
               const PassKey& pass_key) {}

bool RemoveJoinHistory(sql::Database& db,
                       const blink::InterestGroupKey& group_key) {}

bool RemoveBidHistory(sql::Database& db,
                      const blink::InterestGroupKey& group_key) {}

bool RemoveWinHistory(sql::Database& db,
                      const blink::InterestGroupKey& group_key) {}

bool DoRemoveInterestGroup(sql::Database& db,
                           const blink::InterestGroupKey& group_key) {}

bool DoClearClusteredBiddingGroups(sql::Database& db,
                                   const url::Origin owner,
                                   const url::Origin main_frame) {}

// Leaves all the interest groups joined on `joining_origin` except
// `interest_groups_to_keep`. Returns std::nullopt on error, and a (possibly
// empty) list of left interest groups on success.
std::optional<std::vector<std::string>> DoClearOriginJoinedInterestGroups(
    sql::Database& db,
    const url::Origin owner,
    const std::set<std::string>& interest_groups_to_keep,
    const url::Origin joining_origin) {}

#define COMMON_INTEREST_GROUPS_QUERY_FIELDS

// Populate `group` with the current `load` outcome. Prerequisite:
// `load` is an interest group query with the initial fields being
// `COMMON_INTEREST_GROUPS_QUERY_FIELDS`, and there is a row of data returned.
void PopulateInterestGroupFromQueryResult(sql::Statement& load,
                                          const PassKey& passkey,
                                          StorageInterestGroup& group) {}

bool DoLoadInterestGroup(sql::Database& db,
                         const PassKey& passkey,
                         const blink::InterestGroupKey& group_key,
                         StorageInterestGroup& group) {}

bool DoRecordInterestGroupJoin(sql::Database& db,
                               const url::Origin& owner,
                               const std::string& name,
                               base::Time join_time) {}

std::optional<InterestGroupKanonUpdateParameter> DoJoinInterestGroup(
    sql::Database& db,
    const PassKey& passkey,
    const blink::InterestGroup& data,
    const GURL& joining_url,
    base::Time exact_join_time,
    base::Time last_updated,
    base::Time next_update_after) {}

bool DoStoreInterestGroupUpdate(
    sql::Database& db,
    const blink::InterestGroup& group,
    base::Time now,
    base::flat_set<std::string>& positive_kanon_keys) {}

std::optional<InterestGroupKanonUpdateParameter> DoUpdateInterestGroup(
    sql::Database& db,
    const PassKey& passkey,
    const blink::InterestGroupKey& group_key,
    InterestGroupUpdate update,
    base::Time now) {}

bool DoAllowUpdateIfOlderThan(sql::Database& db,
                              const PassKey& passkey,
                              const blink::InterestGroupKey& group_key,
                              base::TimeDelta update_if_older_than,
                              base::Time now) {}

bool DoReportUpdateFailed(sql::Database& db,
                          const blink::InterestGroupKey& group_key,
                          bool parse_failure,
                          base::Time now) {}

bool DoRecordInterestGroupBid(sql::Database& db,
                              const blink::InterestGroupKey& group_key,
                              base::Time bid_time) {}

bool DoRecordInterestGroupBids(sql::Database& db,
                               const blink::InterestGroupSet& group_keys,
                               base::Time bid_time) {}

bool DoRecordInterestGroupWin(sql::Database& db,
                              const blink::InterestGroupKey& group_key,
                              const std::string& ad_json,
                              base::Time win_time) {}

bool DoRecordDebugReportLockout(sql::Database& db,
                                base::Time last_debug_report_sent_time) {}

bool DoRecordDebugReportCooldown(sql::Database& db,
                                 const url::Origin& origin,
                                 base::Time cooldown_start,
                                 DebugReportCooldownType cooldown_type) {}

bool DoUpdateKAnonymity(sql::Database& db,
                        const blink::InterestGroupKey& interest_group_key,
                        const std::vector<std::string>& positive_hashed_keys,
                        const base::Time update_time,
                        bool replace_existing_values,
                        base::Time now) {}

std::optional<base::Time> DoGetLastKAnonymityReported(
    sql::Database& db,
    const std::string& hashed_key) {}

void DoUpdateLastKAnonymityReported(sql::Database& db,
                                    const std::string& hashed_key,
                                    base::Time now) {}

std::optional<std::vector<url::Origin>> DoGetAllInterestGroupOwners(
    sql::Database& db,
    base::Time expiring_after) {}

std::optional<std::vector<url::Origin>> DoGetAllInterestGroupJoiningOrigins(
    sql::Database& db,
    base::Time expiring_after) {}

bool DoRemoveInterestGroupsMatchingOwnerAndJoiner(sql::Database& db,
                                                  url::Origin owner,
                                                  url::Origin joining_origin,
                                                  base::Time expiring_after) {}

std::optional<std::vector<std::pair<url::Origin, url::Origin>>>
DoGetAllInterestGroupOwnerJoinerPairs(sql::Database& db,
                                      base::Time expiring_after) {}

bool GetPreviousWins(sql::Database& db,
                     const blink::InterestGroupKey& group_key,
                     base::Time win_time_after,
                     BiddingBrowserSignalsPtr& output) {}

bool GetJoinCount(sql::Database& db,
                  const blink::InterestGroupKey& group_key,
                  base::Time joined_after,
                  BiddingBrowserSignalsPtr& output) {}

bool GetBidCount(sql::Database& db,
                 const blink::InterestGroupKey& group_key,
                 base::Time now,
                 BiddingBrowserSignalsPtr& output) {}

std::optional<base::Time> DoGetDebugReportLockout(
    sql::Database& db,
    std::optional<base::Time> ignore_before) {}

std::optional<DebugReportCooldown> DoGetDebugReportCooldownForOrigin(
    sql::Database& db,
    const url::Origin& origin,
    std::optional<base::Time> ignore_before) {}

void DoGetDebugReportCooldowns(
    sql::Database& db,
    const base::flat_set<url::Origin>& origins,
    std::optional<base::Time> ignore_before,
    DebugReportLockoutAndCooldowns& debug_report_lockout_and_cooldowns) {}

std::optional<std::vector<std::string>> DoGetInterestGroupNamesForOwner(
    sql::Database& db,
    const url::Origin& owner,
    base::Time now) {}

std::optional<std::vector<std::string>>
DoGetAllRegularInterestGroupNamesForOwner(sql::Database& db,
                                          const url::Origin& owner) {}

std::optional<std::vector<std::string>>
DoGetAllNegativeInterestGroupNamesForOwner(sql::Database& db,
                                           const url::Origin& owner) {}

bool DoGetStoredInterestGroup(sql::Database& db,
                              StorageInterestGroup& db_interest_group,
                              const PassKey& passkey,
                              const blink::InterestGroupKey& group_key,
                              base::Time now) {}

std::optional<std::vector<InterestGroupUpdateParameter>>
DoGetInterestGroupsForUpdate(sql::Database& db,
                             const url::Origin& owner,
                             base::Time now,
                             size_t groups_limit) {}

std::optional<std::vector<StorageInterestGroup>> DoGetInterestGroupsForOwner(
    sql::Database& db,
    const PassKey& passkey,
    const url::Origin& owner,
    base::Time now) {}

std::optional<std::vector<blink::InterestGroupKey>>
DoGetInterestGroupNamesForJoiningOrigin(sql::Database& db,
                                        const url::Origin& joining_origin,
                                        base::Time now) {}

bool DoDeleteInterestGroupData(
    sql::Database& db,
    StoragePartition::StorageKeyMatcherFunction storage_key_matcher) {}

bool DoSetInterestGroupPriority(sql::Database& db,
                                const blink::InterestGroupKey& group_key,
                                double priority) {}

bool DoSetInterestGroupPrioritySignalsOverrides(
    sql::Database& db,
    const blink::InterestGroupKey& group_key,
    const std::optional<base::flat_map<std::string, double>>&
        priority_signals_overrides) {}

bool DeleteOldJoins(sql::Database& db, base::Time cutoff) {}

bool DeleteOldBids(sql::Database& db, base::Time cutoff) {}

bool DeleteOldWins(sql::Database& db, base::Time cutoff) {}

bool DoClearExcessInterestGroups(
    sql::Database& db,
    const url::Origin& affected_origin,
    const std::optional<std::vector<std::string>> maybe_interest_groups,
    size_t max_owner_interest_groups) {}

bool ClearExcessInterestGroups(sql::Database& db,
                               size_t max_owners,
                               size_t max_owner_regular_interest_groups,
                               size_t max_owner_negative_interest_groups) {}

bool ClearExpiredInterestGroups(sql::Database& db,
                                base::Time expiration_before) {}

// Removes interest groups so that per-owner limit is respected. Note that
// we're intentionally not trying to keep this in sync with
// `blink::InterestGroup::EstimateSize()`. There's not a compelling reason to
// keep those exactly aligned and keeping them in sync would require a
// significant amount of extra work.
bool ClearExcessiveStorage(sql::Database& db, size_t max_owner_storage_size) {}

bool ClearExpiredKAnon(sql::Database& db, base::Time cutoff) {}

bool DeleteExpiredDebugReportCooldown(sql::Database& db, base::Time now) {}

bool ClearExpiredBiddingAndAuctionKeys(sql::Database& db, base::Time now) {}

bool DoSetBiddingAndAuctionServerKeys(
    sql::Database& db,
    const url::Origin& coordinator,
    const std::vector<BiddingAndAuctionServerKey>& keys,
    base::Time expiration) {}

std::pair<base::Time, std::vector<BiddingAndAuctionServerKey>>
DoGetBiddingAndAuctionServerKeys(sql::Database& db,
                                 const url::Origin& coordinator) {}

bool DoPerformDatabaseMaintenance(sql::Database& db,
                                  base::Time now,
                                  size_t max_owners,
                                  size_t max_owner_storage_size,
                                  size_t max_owner_regular_interest_groups,
                                  size_t max_owner_negative_interest_groups) {}

base::FilePath DBPath(const base::FilePath& base) {}

sql::DatabaseOptions GetDatabaseOptions() {}

void ReportCreateSchemaResult(
    bool create_schema_result,
    sql::RazeIfIncompatibleResult raze_if_incompatible_result,
    bool missing_metatable_razed) {}

void ReportUpgradeDBResult(bool upgrade_succeeded, int db_version) {}

}  // namespace

constexpr base::TimeDelta InterestGroupStorage::kHistoryLength;
constexpr base::TimeDelta InterestGroupStorage::kMaintenanceInterval;
constexpr base::TimeDelta InterestGroupStorage::kIdlePeriod;
constexpr base::TimeDelta InterestGroupStorage::kUpdateSucceededBackoffPeriod;
constexpr base::TimeDelta InterestGroupStorage::kUpdateFailedBackoffPeriod;

InterestGroupStorage::InterestGroupStorage(const base::FilePath& path)
    :{}

InterestGroupStorage::~InterestGroupStorage() {}

bool InterestGroupStorage::EnsureDBInitialized() {}

bool InterestGroupStorage::InitializeDB() {}

bool InterestGroupStorage::InitializeSchema() {}

std::optional<InterestGroupKanonUpdateParameter>
InterestGroupStorage::JoinInterestGroup(const blink::InterestGroup& group,
                                        const GURL& main_frame_joining_url) {}

void InterestGroupStorage::LeaveInterestGroup(
    const blink::InterestGroupKey& group_key,
    const url::Origin& main_frame) {}

std::vector<std::string> InterestGroupStorage::ClearOriginJoinedInterestGroups(
    const url::Origin& owner,
    const std::set<std::string>& interest_groups_to_keep,
    const url::Origin& main_frame_origin) {}

std::optional<base::Time> InterestGroupStorage::GetDebugReportLockout() {}

std::optional<DebugReportLockoutAndCooldowns>
InterestGroupStorage::GetDebugReportLockoutAndCooldowns(
    base::flat_set<url::Origin> origins) {}

std::optional<InterestGroupKanonUpdateParameter>
InterestGroupStorage::UpdateInterestGroup(
    const blink::InterestGroupKey& group_key,
    InterestGroupUpdate update) {}

void InterestGroupStorage::AllowUpdateIfOlderThan(
    const blink::InterestGroupKey& group_key,
    base::TimeDelta update_if_older_than) {}

void InterestGroupStorage::ReportUpdateFailed(
    const blink::InterestGroupKey& group_key,
    bool parse_failure) {}

void InterestGroupStorage::RecordInterestGroupBids(
    const blink::InterestGroupSet& group_keys) {}

void InterestGroupStorage::RecordInterestGroupWin(
    const blink::InterestGroupKey& group_key,
    const std::string& ad_json) {}

void InterestGroupStorage::RecordDebugReportLockout(
    base::Time last_report_sent_time) {}

void InterestGroupStorage::RecordDebugReportCooldown(
    const url::Origin& origin,
    base::Time cooldown_start,
    DebugReportCooldownType cooldown_type) {}

void InterestGroupStorage::UpdateKAnonymity(
    const blink::InterestGroupKey& interest_group_key,
    const std::vector<std::string>& positive_hashed_keys,
    const base::Time update_time,
    bool replace_existing_values) {}

std::optional<base::Time> InterestGroupStorage::GetLastKAnonymityReported(
    const std::string& hashed_key) {}

void InterestGroupStorage::UpdateLastKAnonymityReported(
    const std::string& hashed_key) {}

std::optional<StorageInterestGroup> InterestGroupStorage::GetInterestGroup(
    const blink::InterestGroupKey& group_key) {}

std::vector<url::Origin> InterestGroupStorage::GetAllInterestGroupOwners() {}

std::vector<StorageInterestGroup>
InterestGroupStorage::GetInterestGroupsForOwner(const url::Origin& owner) {}

std::vector<InterestGroupUpdateParameter>
InterestGroupStorage::GetInterestGroupsForUpdate(const url::Origin& owner,
                                                 size_t groups_limit) {}

std::vector<url::Origin>
InterestGroupStorage::GetAllInterestGroupJoiningOrigins() {}

std::vector<std::pair<url::Origin, url::Origin>>
InterestGroupStorage::GetAllInterestGroupOwnerJoinerPairs() {}

void InterestGroupStorage::RemoveInterestGroupsMatchingOwnerAndJoiner(
    url::Origin owner,
    url::Origin joining_origin) {}

void InterestGroupStorage::DeleteInterestGroupData(
    StoragePartition::StorageKeyMatcherFunction storage_key_matcher) {}

void InterestGroupStorage::DeleteAllInterestGroupData() {}

void InterestGroupStorage::SetInterestGroupPriority(
    const blink::InterestGroupKey& group_key,
    double priority) {}

void InterestGroupStorage::UpdateInterestGroupPriorityOverrides(
    const blink::InterestGroupKey& group_key,
    base::flat_map<std::string,
                   auction_worklet::mojom::PrioritySignalsDoublePtr>
        update_priority_signals_overrides) {}

void InterestGroupStorage::PerformDBMaintenance() {}

std::vector<StorageInterestGroup>
InterestGroupStorage::GetAllInterestGroupsUnfilteredForTesting() {}

void InterestGroupStorage::SetBiddingAndAuctionServerKeys(
    const url::Origin& coordinator,
    const std::vector<BiddingAndAuctionServerKey>& keys,
    base::Time expiration) {}

std::pair<base::Time, std::vector<BiddingAndAuctionServerKey>>
InterestGroupStorage::GetBiddingAndAuctionServerKeys(
    const url::Origin& coordinator) {}

base::Time InterestGroupStorage::GetLastMaintenanceTimeForTesting() const {}

/* static */ int InterestGroupStorage::GetCurrentVersionNumberForTesting() {}

void InterestGroupStorage::DatabaseErrorCallback(int extended_error,
                                                 sql::Statement* stmt) {}

}  // namespace content