// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ash/components/nearby/presence/conversions/nearby_presence_conversions.h"
#include "chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom.h"
#include "third_party/nearby/src/presence/data_element.h"
namespace ash::nearby::presence {
::nearby::internal::DeviceType DeviceTypeFromMojom(
mojom::PresenceDeviceType device_type) {
switch (device_type) {
case mojom::PresenceDeviceType::kUnknown:
return ::nearby::internal::DeviceType::DEVICE_TYPE_UNKNOWN;
case mojom::PresenceDeviceType::kPhone:
return ::nearby::internal::DeviceType::DEVICE_TYPE_PHONE;
case mojom::PresenceDeviceType::kTablet:
return ::nearby::internal::DeviceType::DEVICE_TYPE_TABLET;
case mojom::PresenceDeviceType::kDisplay:
return ::nearby::internal::DeviceType::DEVICE_TYPE_DISPLAY;
case mojom::PresenceDeviceType::kTv:
return ::nearby::internal::DeviceType::DEVICE_TYPE_TV;
case mojom::PresenceDeviceType::kWatch:
return ::nearby::internal::DeviceType::DEVICE_TYPE_WATCH;
case mojom::PresenceDeviceType::kChromeos:
return ::nearby::internal::DeviceType::DEVICE_TYPE_CHROMEOS;
case mojom::PresenceDeviceType::kLaptop:
return ::nearby::internal::DeviceType::DEVICE_TYPE_LAPTOP;
case mojom::PresenceDeviceType::kFoldable:
return ::nearby::internal::DeviceType::DEVICE_TYPE_FOLDABLE;
}
}
mojom::PresenceDeviceType DeviceTypeToMojom(
::nearby::internal::DeviceType device_type) {
switch (device_type) {
case ::nearby::internal::DeviceType::DEVICE_TYPE_UNKNOWN:
return mojom::PresenceDeviceType::kUnknown;
case ::nearby::internal::DeviceType::DEVICE_TYPE_PHONE:
return mojom::PresenceDeviceType::kPhone;
case ::nearby::internal::DeviceType::DEVICE_TYPE_TABLET:
return mojom::PresenceDeviceType::kTablet;
case ::nearby::internal::DeviceType::DEVICE_TYPE_DISPLAY:
return mojom::PresenceDeviceType::kDisplay;
case ::nearby::internal::DeviceType::DEVICE_TYPE_TV:
return mojom::PresenceDeviceType::kTv;
case ::nearby::internal::DeviceType::DEVICE_TYPE_WATCH:
return mojom::PresenceDeviceType::kWatch;
case ::nearby::internal::DeviceType::DEVICE_TYPE_CHROMEOS:
return mojom::PresenceDeviceType::kChromeos;
default:
return mojom::PresenceDeviceType::kUnknown;
}
}
::nearby::internal::DeviceIdentityMetaData MetadataFromMojom(
mojom::Metadata* metadata) {
::nearby::internal::DeviceIdentityMetaData proto;
proto.set_device_type(DeviceTypeFromMojom(metadata->device_type));
proto.set_device_name(metadata->device_name);
proto.set_bluetooth_mac_address(
std::string(metadata->bluetooth_mac_address.begin(),
metadata->bluetooth_mac_address.end()));
proto.set_device_id(
std::string(metadata->device_id.begin(), metadata->device_id.end()));
return proto;
}
mojom::MetadataPtr MetadataToMojom(
::nearby::internal::DeviceIdentityMetaData metadata) {
return mojom::Metadata::New(
DeviceTypeToMojom(metadata.device_type()), metadata.device_name(),
std::vector<uint8_t>(metadata.bluetooth_mac_address().begin(),
metadata.bluetooth_mac_address().end()),
std::vector<uint8_t>(metadata.device_id().begin(),
metadata.device_id().end()));
}
mojom::IdentityType ConvertIdentityTypeToMojom(
::nearby::internal::IdentityType identity_type) {
switch (identity_type) {
case ::nearby::internal::IdentityType::IDENTITY_TYPE_UNSPECIFIED:
return mojom::IdentityType::kIdentityTypeUnspecified;
case ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP:
return mojom::IdentityType::kIdentityTypePrivateGroup;
case ::nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP:
return mojom::IdentityType::kIdentityTypeContactsGroup;
case ::nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC:
return mojom::IdentityType::kIdentityTypePublic;
default:
return mojom::IdentityType::kIdentityTypeUnspecified;
}
}
::nearby::internal::IdentityType ConvertMojomIdentityType(
mojom::IdentityType identity_type) {
switch (identity_type) {
case mojom::IdentityType::kIdentityTypeUnspecified:
return ::nearby::internal::IdentityType::IDENTITY_TYPE_UNSPECIFIED;
case mojom::IdentityType::kIdentityTypePrivateGroup:
return ::nearby::internal::IdentityType::IDENTITY_TYPE_PRIVATE_GROUP;
case mojom::IdentityType::kIdentityTypeContactsGroup:
return ::nearby::internal::IdentityType::IDENTITY_TYPE_CONTACTS_GROUP;
case mojom::IdentityType::kIdentityTypePublic:
return ::nearby::internal::IdentityType::IDENTITY_TYPE_PUBLIC;
default:
return ::nearby::internal::IdentityType::IDENTITY_TYPE_UNSPECIFIED;
}
}
mojom::CredentialType ConvertCredentialTypeToMojom(
::nearby::internal::CredentialType credential_type) {
switch (credential_type) {
case ::nearby::internal::CredentialType::CREDENTIAL_TYPE_UNKNOWN:
return mojom::CredentialType::kCredentialTypeUnknown;
case ::nearby::internal::CredentialType::CREDENTIAL_TYPE_DEVICE:
return mojom::CredentialType::kCredentialTypeDevice;
case ::nearby::internal::CredentialType::CREDENTIAL_TYPE_GAIA:
return mojom::CredentialType::kCredentialTypeGaia;
default:
return mojom::CredentialType::kCredentialTypeUnknown;
}
}
::nearby::internal::CredentialType ConvertMojomCredentialType(
mojom::CredentialType credential_type) {
switch (credential_type) {
case mojom::CredentialType::kCredentialTypeUnknown:
return ::nearby::internal::CredentialType::CREDENTIAL_TYPE_UNKNOWN;
case mojom::CredentialType::kCredentialTypeDevice:
return ::nearby::internal::CredentialType::CREDENTIAL_TYPE_DEVICE;
case mojom::CredentialType::kCredentialTypeGaia:
return ::nearby::internal::CredentialType::CREDENTIAL_TYPE_GAIA;
default:
return ::nearby::internal::CredentialType::CREDENTIAL_TYPE_UNKNOWN;
}
}
mojom::ActionType ConvertActionTypeToMojom(uint32_t action) {
switch (::nearby::presence::ActionBit(action)) {
case ::nearby::presence::ActionBit::kCallTransferAction:
return mojom::ActionType::kCallTransferAction;
case ::nearby::presence::ActionBit::kActiveUnlockAction:
return mojom::ActionType::kActiveUnlockAction;
case ::nearby::presence::ActionBit::kNearbyShareAction:
return mojom::ActionType::kNearbyShareAction;
case ::nearby::presence::ActionBit::kInstantTetheringAction:
return mojom::ActionType::kInstantTetheringAction;
case ::nearby::presence::ActionBit::kPhoneHubAction:
return mojom::ActionType::kPhoneHubAction;
case ::nearby::presence::ActionBit::kPresenceManagerAction:
return mojom::ActionType::kPresenceManagerAction;
case ::nearby::presence::ActionBit::kFinderAction:
return mojom::ActionType::kFinderAction;
case ::nearby::presence::ActionBit::kFastPairSassAction:
return mojom::ActionType::kFastPairSassAction;
case ::nearby::presence::ActionBit::kTapToTransferAction:
return mojom::ActionType::kTapToTransferAction;
case ::nearby::presence::ActionBit::kLastAction:
return mojom::ActionType::kLastAction;
}
}
mojo_base::mojom::AbslStatusCode ConvertStatusToMojom(absl::Status status) {
switch (status.code()) {
case absl::StatusCode::kOk:
return mojo_base::mojom::AbslStatusCode::kOk;
case absl::StatusCode::kCancelled:
return mojo_base::mojom::AbslStatusCode::kCancelled;
case absl::StatusCode::kUnknown:
return mojo_base::mojom::AbslStatusCode::kUnknown;
case absl::StatusCode::kInvalidArgument:
return mojo_base::mojom::AbslStatusCode::kInvalidArgument;
case absl::StatusCode::kDeadlineExceeded:
return mojo_base::mojom::AbslStatusCode::kDeadlineExceeded;
case absl::StatusCode::kNotFound:
return mojo_base::mojom::AbslStatusCode::kNotFound;
case absl::StatusCode::kAlreadyExists:
return mojo_base::mojom::AbslStatusCode::kAlreadyExists;
case absl::StatusCode::kPermissionDenied:
return mojo_base::mojom::AbslStatusCode::kPermissionDenied;
case absl::StatusCode::kResourceExhausted:
return mojo_base::mojom::AbslStatusCode::kResourceExhausted;
case absl::StatusCode::kFailedPrecondition:
return mojo_base::mojom::AbslStatusCode::kFailedPrecondition;
case absl::StatusCode::kAborted:
return mojo_base::mojom::AbslStatusCode::kAborted;
case absl::StatusCode::kOutOfRange:
return mojo_base::mojom::AbslStatusCode::kOutOfRange;
case absl::StatusCode::kUnimplemented:
return mojo_base::mojom::AbslStatusCode::kUnimplemented;
case absl::StatusCode::kInternal:
return mojo_base::mojom::AbslStatusCode::kInternal;
case absl::StatusCode::kUnavailable:
return mojo_base::mojom::AbslStatusCode::kUnavailable;
case absl::StatusCode::kDataLoss:
return mojo_base::mojom::AbslStatusCode::kDataLoss;
case absl::StatusCode::kUnauthenticated:
return mojo_base::mojom::AbslStatusCode::kUnauthenticated;
case absl::StatusCode::
kDoNotUseReservedForFutureExpansionUseDefaultInSwitchInstead_:
NOTREACHED();
}
}
mojom::SharedCredentialPtr SharedCredentialToMojom(
::nearby::internal::SharedCredential shared_credential) {
return mojom::SharedCredential::New(
std::vector<uint8_t>(shared_credential.key_seed().begin(),
shared_credential.key_seed().end()),
shared_credential.start_time_millis(),
shared_credential.end_time_millis(),
std::vector<uint8_t>(
shared_credential.encrypted_metadata_bytes_v0().begin(),
shared_credential.encrypted_metadata_bytes_v0().end()),
std::vector<uint8_t>(
shared_credential.metadata_encryption_key_tag_v0().begin(),
shared_credential.metadata_encryption_key_tag_v0().end()),
std::vector<uint8_t>(
shared_credential.connection_signature_verification_key().begin(),
shared_credential.connection_signature_verification_key().end()),
std::vector<uint8_t>(
shared_credential.advertisement_signature_verification_key().begin(),
shared_credential.advertisement_signature_verification_key().end()),
ConvertIdentityTypeToMojom(shared_credential.identity_type()),
std::vector<uint8_t>(shared_credential.version().begin(),
shared_credential.version().end()),
ConvertCredentialTypeToMojom(shared_credential.credential_type()),
std::vector<uint8_t>(
shared_credential.encrypted_metadata_bytes_v1().begin(),
shared_credential.encrypted_metadata_bytes_v1().end()),
std::vector<uint8_t>(
shared_credential.identity_token_short_salt_adv_hmac_key_v1().begin(),
shared_credential.identity_token_short_salt_adv_hmac_key_v1().end()),
shared_credential.id(), shared_credential.dusi(),
shared_credential.signature_version(),
std::vector<uint8_t>(
shared_credential.identity_token_extended_salt_adv_hmac_key_v1()
.begin(),
shared_credential.identity_token_extended_salt_adv_hmac_key_v1()
.end()),
std::vector<uint8_t>(
shared_credential.identity_token_signed_adv_hmac_key_v1().begin(),
shared_credential.identity_token_signed_adv_hmac_key_v1().end()));
}
::nearby::internal::SharedCredential SharedCredentialFromMojom(
mojom::SharedCredential* shared_credential) {
::nearby::internal::SharedCredential proto;
proto.set_key_seed(std::string(shared_credential->key_seed.begin(),
shared_credential->key_seed.end()));
proto.set_start_time_millis(shared_credential->start_time_millis);
proto.set_end_time_millis(shared_credential->end_time_millis);
proto.set_encrypted_metadata_bytes_v0(
std::string(shared_credential->encrypted_metadata_bytes_v0.begin(),
shared_credential->encrypted_metadata_bytes_v0.end()));
proto.set_metadata_encryption_key_tag_v0(
std::string(shared_credential->metadata_encryption_key_tag_v0.begin(),
shared_credential->metadata_encryption_key_tag_v0.end()));
proto.set_connection_signature_verification_key(std::string(
shared_credential->connection_signature_verification_key.begin(),
shared_credential->connection_signature_verification_key.end()));
proto.set_advertisement_signature_verification_key(std::string(
shared_credential->advertisement_signature_verification_key.begin(),
shared_credential->advertisement_signature_verification_key.end()));
proto.set_identity_type(
ConvertMojomIdentityType(shared_credential->identity_type));
proto.set_version(std::string(shared_credential->version.begin(),
shared_credential->version.end()));
proto.set_credential_type(
ConvertMojomCredentialType(shared_credential->credential_type));
proto.set_encrypted_metadata_bytes_v1(
std::string(shared_credential->encrypted_metadata_bytes_v1.begin(),
shared_credential->encrypted_metadata_bytes_v1.end()));
proto.set_identity_token_short_salt_adv_hmac_key_v1(std::string(
shared_credential->identity_token_short_salt_adv_hmac_key_v1.begin(),
shared_credential->identity_token_short_salt_adv_hmac_key_v1.end()));
proto.set_id(shared_credential->id);
proto.set_dusi(shared_credential->dusi);
proto.set_signature_version(shared_credential->signature_version);
proto.set_identity_token_extended_salt_adv_hmac_key_v1(std::string(
shared_credential->identity_token_extended_salt_adv_hmac_key_v1.begin(),
shared_credential->identity_token_extended_salt_adv_hmac_key_v1.end()));
proto.set_identity_token_signed_adv_hmac_key_v1(std::string(
shared_credential->identity_token_signed_adv_hmac_key_v1.begin(),
shared_credential->identity_token_signed_adv_hmac_key_v1.end()));
return proto;
}
mojom::PresenceDevicePtr BuildPresenceMojomDevice(
::nearby::presence::PresenceDevice device) {
std::vector<mojom::ActionType> actions;
for (auto action : device.GetActions()) {
actions.push_back(ConvertActionTypeToMojom(action.GetActionIdentifier()));
}
// TODO(b/276642472): Properly plumb type and stable_device_id.
return mojom::PresenceDevice::New(
device.GetEndpointId(), std::move(actions),
/*stable_device_id=*/std::nullopt,
MetadataToMojom(device.GetDeviceIdentityMetadata()),
device.GetDecryptSharedCredential()
? SharedCredentialToMojom(device.GetDecryptSharedCredential().value())
: nullptr);
}
} // namespace ash::nearby::presence