blob: e0d44895d847ac7e1c9ca1b4681d4dea78de8b17 [file] [log] [blame]
// Copyright 2022 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_priority_util.h"
#include <optional>
#include <string>
#include "base/containers/flat_map.h"
#include "base/time/time.h"
#include "content/browser/interest_group/storage_interest_group.h"
#include "third_party/blink/public/common/interest_group/auction_config.h"
#include "third_party/blink/public/common/interest_group/interest_group.h"
#include "url/origin.h"
namespace content {
double CalculateInterestGroupPriority(
const blink::AuctionConfig& auction_config,
const StorageInterestGroup& storage_interest_group,
const base::Time auction_start_time,
const base::flat_map<std::string, double>& priority_vector,
std::optional<double> first_dot_product_priority) {
// Empty priority vectors should be ignored, so updating an interest group can
// set an empty priority vector to disable it.
DCHECK(!priority_vector.empty());
const blink::InterestGroup& interest_group =
storage_interest_group.interest_group;
// Calculate the time since the interest group was joined. Force it to be
// between 0 and 30 days. Less than 0 could happen due to clock changes. The
// expiration time is 30 days, but could exceed it due to races or clock
// changes in the middle of an auction, though seems unlikely.
base::TimeDelta age = auction_start_time - storage_interest_group.join_time;
age = std::max(age, base::TimeDelta());
age = std::min(age, base::Days(30));
// TODO(crbug.com/40231372): Add browserSignals.age.
base::flat_map<std::string, double> browser_signals{
{"browserSignals.one", 1},
{"browserSignals.basePriority", interest_group.priority},
{"browserSignals.firstDotProductPriority",
first_dot_product_priority.value_or(0)},
{"browserSignals.ageInMinutes", age.InMinutes()},
{"browserSignals.ageInMinutesMax60", std::min(age.InMinutes(), 60)},
{"browserSignals.ageInHoursMax24", std::min(age.InHours(), 24)},
{"browserSignals.ageInDaysMax30", std::min(age.InDays(), 30)},
};
// Ordered list of priority signals map. Order is
// 1) `interest_group.priority_signals_overrides`
// 2) `browser_signals`
// 3) `auction_config.per_buyer_priority_signals`
// 4) `auction_config.all_buyers_priority_signals`
//
// All values except `browser_signals` may not be present. `browser_signals`
// does not technically have to be in front of the auction config values,
// since auction configs are prevented from overriding its values by the
// AuctionConfig typemap.
std::vector<const base::flat_map<std::string, double>*> maps;
maps.reserve(4);
if (interest_group.priority_signals_overrides)
maps.push_back(&interest_group.priority_signals_overrides.value());
maps.push_back(&browser_signals);
if (auction_config.non_shared_params.per_buyer_priority_signals) {
auto per_buyer_priority_signals =
auction_config.non_shared_params.per_buyer_priority_signals->find(
interest_group.owner);
if (per_buyer_priority_signals !=
auction_config.non_shared_params.per_buyer_priority_signals->end()) {
maps.push_back(&per_buyer_priority_signals->second);
}
}
if (auction_config.non_shared_params.all_buyers_priority_signals) {
maps.push_back(
&auction_config.non_shared_params.all_buyers_priority_signals.value());
}
double caclulated_priority = 0;
for (const auto& priority_pair : priority_vector) {
for (const auto* map : maps) {
const auto signals_pair = map->find(priority_pair.first);
if (signals_pair == map->end())
continue;
caclulated_priority += signals_pair->second * priority_pair.second;
break;
}
}
return caclulated_priority;
}
} // namespace content