#include "services/metrics/public/cpp/ukm_source_id.h"
#include <cmath>
#include <string>
#include "base/atomic_sequence_num.h"
#include "base/check.h"
#include "base/check_op.h"
#include "base/rand_util.h"
namespace ukm {
namespace {
const int64_t kLowBitsMask = (INT64_C(1) << 32) - 1;
int64_t GetNumTypeBits() {
return std::ceil(
std::log2(static_cast<int64_t>(SourceIdObj::Type::kMaxValue) + 1));
}
}
SourceIdObj SourceIdObj::New() {
const static int64_t process_id_bits =
static_cast<int64_t>(base::RandUint64()) & ~kLowBitsMask;
static base::AtomicSequenceNumber seq;
SourceIdObj local_id =
FromOtherId(seq.GetNext() + 1, SourceIdObj::Type::DEFAULT);
return SourceIdObj((local_id.value_ & kLowBitsMask) | process_id_bits);
}
SourceIdObj SourceIdObj::FromOtherId(int64_t other_id, SourceIdObj::Type type) {
static const int64_t kNumTypeBits = GetNumTypeBits();
static const int64_t kTypeMask = (INT64_C(1) << kNumTypeBits) - 1;
const int64_t type_bits = static_cast<int64_t>(type);
DCHECK_EQ(type_bits, type_bits & kTypeMask);
return SourceIdObj((other_id << kNumTypeBits) | type_bits);
}
SourceIdObj::Type SourceIdObj::GetType() const {
static const int64_t kNumTypeBits = GetNumTypeBits();
static const int64_t kTypeMask = (INT64_C(1) << kNumTypeBits) - 1;
return static_cast<SourceIdObj::Type>(value_ & kTypeMask);
}
SourceId AssignNewSourceId() {
return ukm::SourceIdObj::New().ToInt64();
}
SourceId ConvertToSourceId(int64_t other_id, SourceIdType id_type) {
DCHECK(id_type != SourceIdType::WEBAPK_ID);
DCHECK(id_type != SourceIdType::PAYMENT_APP_ID);
DCHECK(id_type != SourceIdType::WEB_IDENTITY_ID);
return ukm::SourceIdObj::FromOtherId(other_id, id_type).ToInt64();
}
SourceIdType GetSourceIdType(SourceId source_id) {
return ukm::SourceIdObj::FromInt64(source_id).GetType();
}
std::string GetSourceIdTypeDebugString(SourceId source_id) {
const auto source_type = GetSourceIdType(source_id);
switch (source_type) {
case SourceIdObj::Type::DEFAULT:
return "DEFAULT";
case SourceIdObj::Type::NAVIGATION_ID:
return "NAVIGATION_ID";
case SourceIdObj::Type::APP_ID:
return "APP_ID";
case SourceIdObj::Type::HISTORY_ID:
return "HISTORY_ID";
case SourceIdObj::Type::WEBAPK_ID:
return "WEBAPK_ID";
case SourceIdObj::Type::PAYMENT_APP_ID:
return "PAYMENT_APP_ID";
case SourceIdObj::Type::DEPRECATED_DESKTOP_WEB_APP_ID:
return "DESKTOP_WEB_APP_ID";
case SourceIdObj::Type::WORKER_ID:
return "WORKER_ID";
case SourceIdObj::Type::NO_URL_ID:
return "NO_URL_ID";
case SourceIdObj::Type::REDIRECT_ID:
return "REDIRECT_ID";
case SourceIdObj::Type::WEB_IDENTITY_ID:
return "WEB_IDENTITY_ID";
case SourceIdObj::Type::CHROMEOS_WEBSITE_ID:
return "CHROMEOS_WEBSITE_ID";
case SourceIdObj::Type::EXTENSION_ID:
return "EXTENSION_ID";
case SourceIdObj::Type::NOTIFICATION_ID:
return "NOTIFICATION_ID";
case SourceIdObj::Type::CDM_ID:
return "CDM_ID";
}
}
SourceId NoURLSourceId() {
static const SourceId source_id =
SourceIdObj::FromOtherId(AssignNewSourceId(), SourceIdType::NO_URL_ID)
.ToInt64();
return source_id;
}
}