#include <utility>
#include "chrome/services/sharing/public/cpp/advertisement.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
namespace {
constexpr uint8_t kVersionBitmask = 0b111;
constexpr uint8_t kDeviceTypeBitmask = 0b111;
const uint8_t kMinimumSize =
*/
1 + sharing::Advertisement::kSaltSize +
sharing::Advertisement::kMetadataEncryptionKeyHashByteSize;
uint8_t ConvertVersion(int version) {
return static_cast<uint8_t>((version & kVersionBitmask) << 5);
}
uint8_t ConvertDeviceType(nearby_share::mojom::ShareTargetType type) {
return static_cast<uint8_t>((static_cast<int32_t>(type) & kDeviceTypeBitmask)
<< 1);
}
uint8_t ConvertHasDeviceName(bool hasDeviceName) {
return static_cast<uint8_t>((hasDeviceName ? 0 : 1) << 4);
}
}
namespace sharing {
std::unique_ptr<Advertisement> Advertisement::NewInstance(
base::span<const uint8_t, kSaltSize> salt,
base::span<const uint8_t, kMetadataEncryptionKeyHashByteSize>
encrypted_metadata_key,
nearby_share::mojom::ShareTargetType device_type,
std::optional<std::string> device_name) {
if (device_name && device_name->size() > UINT8_MAX) {
LOG(ERROR) << "Failed to create advertisement because device name "
"was over UINT8_MAX: "
<< device_name->size();
return nullptr;
}
return base::WrapUnique(new sharing::Advertisement(
0, std::move(salt), std::move(encrypted_metadata_key),
device_type, std::move(device_name)));
}
Advertisement::~Advertisement() = default;
Advertisement::Advertisement(Advertisement&& other) = default;
std::vector<uint8_t> Advertisement::ToEndpointInfo() {
int size = kMinimumSize + (device_name_ ? 1 : 0) +
(device_name_ ? device_name_->size() : 0);
std::vector<uint8_t> endpoint_info;
endpoint_info.reserve(size);
endpoint_info.push_back(
static_cast<uint8_t>(ConvertVersion(version_) |
ConvertHasDeviceName(device_name_.has_value()) |
ConvertDeviceType(device_type_)));
endpoint_info.insert(endpoint_info.end(), salt_.begin(), salt_.end());
endpoint_info.insert(endpoint_info.end(), encrypted_metadata_key_.begin(),
encrypted_metadata_key_.end());
if (device_name_) {
endpoint_info.push_back(static_cast<uint8_t>(device_name_->size() & 0xff));
endpoint_info.insert(endpoint_info.end(), device_name_->begin(),
device_name_->end());
}
return endpoint_info;
}
Advertisement::Advertisement(
int version,
base::span<const uint8_t, kSaltSize> salt,
base::span<const uint8_t, kMetadataEncryptionKeyHashByteSize>
encrypted_metadata_key,
nearby_share::mojom::ShareTargetType device_type,
std::optional<std::string> device_name)
: version_(version),
device_type_(device_type),
device_name_(std::move(device_name)) {
base::span(salt_).copy_from(salt);
base::span(encrypted_metadata_key_).copy_from(encrypted_metadata_key);
}
}