Add vendor ID from a registered receive surface to the advertisement.

PiperOrigin-RevId: 639091253
This commit is contained in:
Anay Wadhera
2024-05-31 11:11:05 -07:00
committed by Copybara-Service
parent 5000f0a4d4
commit ec3cf6ca26
8 changed files with 163 additions and 23 deletions
+6 -9
View File
@@ -58,11 +58,6 @@ enum class TlvTypes : uint8_t {
kQrCode = 1,
kVendorId = 2,
};
enum class VendorId : uint8_t {
kNone = 0,
kSamsung = 1,
};
// The length in bytes of the vendor ID in the TLV advertisement.
constexpr uint8_t kVendorIdLength = 1;
@@ -162,7 +157,7 @@ std::vector<uint8_t> Advertisement::ToEndpointInfo() const {
// the ID itself (1 byte).
int size = kMinimumSize + (device_name_.has_value() ? 1 : 0) +
(device_name_.has_value() ? device_name_->size() : 0) +
(vendor_id_ != static_cast<uint8_t>(VendorId::kNone)
(vendor_id_ != static_cast<uint8_t>(BlockedVendorId::kNone)
? (kTlvMinimumLength + kVendorIdLength)
: 0);
@@ -183,7 +178,7 @@ std::vector<uint8_t> Advertisement::ToEndpointInfo() const {
}
// Add vendor ID if it is not the default |VendorId::kNone|.
if (vendor_id_ != static_cast<uint8_t>(VendorId::kNone)) {
if (vendor_id_ != static_cast<uint8_t>(BlockedVendorId::kNone)) {
// Add vendor ID in TLV format.
endpoint_info.push_back(static_cast<uint8_t>(TlvTypes::kVendorId));
// Length is 1 byte.
@@ -241,7 +236,7 @@ std::unique_ptr<Advertisement> Advertisement::FromEndpointInfo(
iter += device_name_length;
}
uint8_t vendor_id = static_cast<uint8_t>(VendorId::kNone);
uint8_t vendor_id = static_cast<uint8_t>(BlockedVendorId::kNone);
while (endpoint_info.end() - iter >= kTlvMinimumLength) {
// We will parse a TLV element now.
TlvTypes type = static_cast<TlvTypes>(*iter++);
@@ -259,13 +254,15 @@ std::unique_ptr<Advertisement> Advertisement::FromEndpointInfo(
vendor_id = ConvertVendorId(*iter++);
break;
case TlvTypes::kQrCode:
NL_LOG(INFO) << "Found QR code data, skipping.";
// TODO: b/341984671 - Implement handling for this TLV type.
iter += value_len;
break;
default:
NL_LOG(ERROR) << "Unknown TLV type: " << static_cast<uint8_t>(type);
iter += value_len;
break;
}
iter += value_len;
}
return Advertisement::NewInstance(
+7
View File
@@ -36,6 +36,13 @@ class Advertisement {
public:
static constexpr uint8_t kSaltSize = 2;
static constexpr uint8_t kMetadataEncryptionKeyHashByteSize = 14;
// LINT.IfChange()
// Lists supported vendors for target blocking.
enum class BlockedVendorId : uint8_t {
kNone = 0,
kSamsung = 1,
};
// LINT.ThenChange(//depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/sharing/SharingOptions.java:VendorId)
static std::unique_ptr<Advertisement> NewInstance(
std::vector<uint8_t> salt, std::vector<uint8_t> encrypted_metadata_key,
+3 -1
View File
@@ -22,6 +22,7 @@
#include "absl/strings/string_view.h"
#include "internal/base/observer_list.h"
#include "sharing/advertisement.h"
#include "sharing/attachment.h"
#include "sharing/internal/api/sharing_rpc_notifier.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
@@ -87,7 +88,8 @@ void FakeNearbySharingService::UnregisterSendSurface(
// Registers a receiver surface for handling payload transfer status.
void FakeNearbySharingService::RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state,
uint8_t vendor_id, std::function<void(StatusCodes)> status_codes_callback) {
Advertisement::BlockedVendorId vendor_id,
std::function<void(StatusCodes)> status_codes_callback) {
if (state == ReceiveSurfaceState::kForeground) {
foreground_receive_transfer_callbacks_.AddObserver(transfer_callback);
} else {
+1 -1
View File
@@ -64,7 +64,7 @@ class FakeNearbySharingService : public NearbySharingService {
// Registers a receiver surface for handling payload transfer status.
void RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state,
uint8_t vendor_id,
Advertisement::BlockedVendorId vendor_id,
std::function<void(StatusCodes)> status_codes_callback) override;
// Unregisters the current receive surface.
+2 -1
View File
@@ -23,6 +23,7 @@
#include "absl/strings/string_view.h"
#include "internal/network/url.h"
#include "sharing/advertisement.h"
#include "sharing/attachment.h"
#include "sharing/internal/api/sharing_rpc_notifier.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
@@ -147,7 +148,7 @@ class NearbySharingService {
// advertises the vendor ID specified by |vendor_id|.
virtual void RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state,
uint8_t vendor_id,
Advertisement::BlockedVendorId vendor_id,
std::function<void(StatusCodes)> status_codes_callback) = 0;
// Unregisters the current receive surface.
+51 -5
View File
@@ -16,6 +16,7 @@
#include <stdint.h>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <filesystem> // NOLINT(build/c++17)
@@ -112,6 +113,7 @@ namespace nearby {
namespace sharing {
namespace {
using BlockedVendorId = ::nearby::sharing::Advertisement::BlockedVendorId;
using ::nearby::sharing::api::SharingPlatform;
using ::nearby::sharing::proto::DataUsage;
using ::nearby::sharing::proto::DeviceVisibility;
@@ -151,6 +153,13 @@ constexpr absl::string_view kConnectionListenerName = "nearby-share-service";
constexpr absl::string_view kScreenStateListenerName = "nearby-share-service";
constexpr absl::string_view kProfileRelativePath = "Google/Nearby/Sharing";
bool ShouldBlockSurfaceRegistration(BlockedVendorId registering_vendor_id,
BlockedVendorId blocked_vendor_id) {
return blocked_vendor_id != BlockedVendorId::kNone &&
registering_vendor_id != BlockedVendorId::kNone &&
registering_vendor_id != blocked_vendor_id;
}
} // namespace
NearbySharingServiceImpl::NearbySharingServiceImpl(
@@ -495,7 +504,8 @@ void NearbySharingServiceImpl::UnregisterSendSurface(
void NearbySharingServiceImpl::RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state,
uint8_t vendor_id, std::function<void(StatusCodes)> status_codes_callback) {
BlockedVendorId vendor_id,
std::function<void(StatusCodes)> status_codes_callback) {
RunOnNearbySharingServiceThread(
"api_register_receive_surface",
[this, transfer_callback, state, vendor_id,
@@ -518,6 +528,7 @@ void NearbySharingServiceImpl::RegisterReceiveSurface(
StatusCodes::kNoAvailableConnectionMedium);
return;
}
BlockedVendorId before_registration_vendor_id = GetVendorId();
// We specifically allow re-registering without error, so it is clear to
// caller that the transfer_callback is currently registered.
@@ -536,6 +547,17 @@ void NearbySharingServiceImpl::RegisterReceiveSurface(
"different state.";
std::move(status_codes_callback)(StatusCodes::kInvalidArgument);
return;
} else if (ShouldBlockSurfaceRegistration(
vendor_id, before_registration_vendor_id)) {
// Block alternate vendor ID registration.
NL_LOG(ERROR) << __func__
<< ": disallowing registration of a receive surface "
"that has vendor_id "
<< static_cast<uint32_t>(vendor_id)
<< " because the current vendor_id is "
<< static_cast<uint32_t>(GetVendorId());
std::move(status_codes_callback)(StatusCodes::kInvalidArgument);
return;
}
// If the receive surface to be registered is a foreground surface, let
@@ -1510,7 +1532,31 @@ void NearbySharingServiceImpl::SetupBluetoothAdapter() {
InvalidateSurfaceState();
}
absl::flat_hash_map<TransferUpdateCallback*, uint8_t>&
BlockedVendorId NearbySharingServiceImpl::GetVendorId() const {
// Prefer a vendor ID provided by a foreground surface.
auto fg_vendor_it =
std::find_if(foreground_receive_callbacks_map_.begin(),
foreground_receive_callbacks_map_.end(),
[](const auto& receive_callback) {
return receive_callback.second != BlockedVendorId::kNone;
});
if (fg_vendor_it != foreground_receive_callbacks_map_.end()) {
return fg_vendor_it->second;
}
// Look through background surfaces.
auto bg_vendor_it =
std::find_if(background_receive_callbacks_map_.begin(),
background_receive_callbacks_map_.end(),
[](const auto& receive_callback) {
return receive_callback.second != BlockedVendorId::kNone;
});
if (bg_vendor_it != foreground_receive_callbacks_map_.end()) {
return bg_vendor_it->second;
}
return BlockedVendorId::kNone;
}
absl::flat_hash_map<TransferUpdateCallback*, BlockedVendorId>&
NearbySharingServiceImpl::GetReceiveCallbacksMapFromState(
ReceiveSurfaceState state) {
switch (state) {
@@ -1563,9 +1609,9 @@ NearbySharingServiceImpl::CreateEndpointInfo(
ShareTargetType device_type =
static_cast<ShareTargetType>(device_info_.GetDeviceType());
std::unique_ptr<Advertisement> advertisement =
Advertisement::NewInstance(std::move(salt), std::move(encrypted_key),
device_type, device_name, /*vendor_id=*/0);
std::unique_ptr<Advertisement> advertisement = Advertisement::NewInstance(
std::move(salt), std::move(encrypted_key), device_type, device_name,
static_cast<uint8_t>(GetVendorId()));
if (advertisement) {
return advertisement->ToEndpointInfo();
} else {
+8 -4
View File
@@ -133,7 +133,7 @@ class NearbySharingServiceImpl
std::function<void(StatusCodes)> status_codes_callback) override;
void RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state,
uint8_t vendor_id,
Advertisement::BlockedVendorId vendor_id,
std::function<void(StatusCodes)> status_codes_callback) override;
void UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback,
@@ -247,8 +247,12 @@ class NearbySharingServiceImpl
void SetupBluetoothAdapter();
absl::flat_hash_map<TransferUpdateCallback*, uint8_t>&
absl::flat_hash_map<TransferUpdateCallback*, Advertisement::BlockedVendorId>&
GetReceiveCallbacksMapFromState(ReceiveSurfaceState state);
// Retrieves the current vendor ID, defaulting to kNone if no surface has been
// registered with a different vendor ID. This function will always return one
// vendor ID, preferring a foreground surface vendor ID if available.
Advertisement::BlockedVendorId GetVendorId() const;
bool IsVisibleInBackground(proto::DeviceVisibility visibility);
std::optional<std::vector<uint8_t>> CreateEndpointInfo(
proto::DeviceVisibility visibility,
@@ -520,10 +524,10 @@ class NearbySharingServiceImpl
// A list of service observers.
ObserverList<NearbySharingService::Observer> observers_;
// A map of foreground receiver callbacks -> vendor ID.
absl::flat_hash_map<TransferUpdateCallback*, uint8_t>
absl::flat_hash_map<TransferUpdateCallback*, Advertisement::BlockedVendorId>
foreground_receive_callbacks_map_;
// A map of background receiver callbacks -> vendor ID.
absl::flat_hash_map<TransferUpdateCallback*, uint8_t>
absl::flat_hash_map<TransferUpdateCallback*, Advertisement::BlockedVendorId>
background_receive_callbacks_map_;
// A list of foreground receivers for transfer updates on the send surface.
ObserverList<TransferUpdateCallback> foreground_send_transfer_callbacks_;
+85 -2
View File
@@ -527,12 +527,14 @@ class NearbySharingServiceImplTest : public testing::Test {
NearbySharingService::StatusCodes RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback,
NearbySharingService::ReceiveSurfaceState state) {
NearbySharingService::ReceiveSurfaceState state,
uint8_t vendor_id = kVendorId) {
NearbySharingService::StatusCodes result =
NearbySharingService::StatusCodes::kError;
absl::Notification notification;
service_->RegisterReceiveSurface(
transfer_callback, state, kVendorId,
transfer_callback, state,
static_cast<Advertisement::BlockedVendorId>(vendor_id),
[&](NearbySharingService::StatusCodes status_codes) {
result = status_codes;
notification.Notify();
@@ -2056,6 +2058,87 @@ TEST_F(
EXPECT_FALSE(service_->IsInHighVisibility());
}
TEST_F(NearbySharingServiceImplTest,
RegisterReceiveSurfaceWithVendorId_StartAdvertisingVendorId) {
SetConnectionType(ConnectionType::kWifi);
preference_manager().SetInteger(
prefs::kNearbySharingBackgroundVisibilityName,
static_cast<int>(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS));
FlushTesting();
// Register background receive surface with vendor ID 1.
MockTransferUpdateCallback background_transfer_callback;
NearbySharingService::StatusCodes result = RegisterReceiveSurface(
&background_transfer_callback,
NearbySharingService::ReceiveSurfaceState::kBackground,
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
ASSERT_EQ(result, NearbySharingService::StatusCodes::kOk);
ASSERT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
auto endpoint_info =
fake_nearby_connections_manager_->advertising_endpoint_info();
auto advertisement = Advertisement::FromEndpointInfo(*endpoint_info);
EXPECT_EQ(advertisement->vendor_id(),
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
}
TEST_F(NearbySharingServiceImplTest,
RegisterReceiveSurfaceWithDifferentVendorIdIsBlocked) {
SetConnectionType(ConnectionType::kWifi);
preference_manager().SetInteger(
prefs::kNearbySharingBackgroundVisibilityName,
static_cast<int>(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS));
FlushTesting();
// Register background receive surface with vendor ID 1.
MockTransferUpdateCallback background_transfer_callback;
NearbySharingService::StatusCodes result = RegisterReceiveSurface(
&background_transfer_callback,
NearbySharingService::ReceiveSurfaceState::kBackground,
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
ASSERT_EQ(result, NearbySharingService::StatusCodes::kOk);
ASSERT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
// Register foreground receive surface with different vendor ID.
MockTransferUpdateCallback foreground_transfer_callback;
result = RegisterReceiveSurface(
&foreground_transfer_callback,
NearbySharingService::ReceiveSurfaceState::kForeground, /*vendor_id=*/2);
EXPECT_EQ(result, NearbySharingService::StatusCodes::kInvalidArgument);
EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
}
TEST_F(NearbySharingServiceImplTest,
RegisterReceiveSurfaceWithVendorId_OkWithBgNoVendorId) {
SetConnectionType(ConnectionType::kWifi);
preference_manager().SetInteger(
prefs::kNearbySharingBackgroundVisibilityName,
static_cast<int>(DeviceVisibility::DEVICE_VISIBILITY_ALL_CONTACTS));
FlushTesting();
// Register background receive surface with vendor ID 0.
MockTransferUpdateCallback background_transfer_callback;
NearbySharingService::StatusCodes result = RegisterReceiveSurface(
&background_transfer_callback,
NearbySharingService::ReceiveSurfaceState::kBackground,
static_cast<uint8_t>(Advertisement::BlockedVendorId::kNone));
ASSERT_EQ(result, NearbySharingService::StatusCodes::kOk);
ASSERT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
// Register foreground receive surface with vendor ID 1.
MockTransferUpdateCallback foreground_transfer_callback;
result = RegisterReceiveSurface(
&foreground_transfer_callback,
NearbySharingService::ReceiveSurfaceState::kForeground,
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
EXPECT_EQ(result, NearbySharingService::StatusCodes::kOk);
EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising());
// Verify endpoint info is advertising the foreground surface.
auto endpoint_info =
fake_nearby_connections_manager_->advertising_endpoint_info();
auto advertisement = Advertisement::FromEndpointInfo(*endpoint_info);
EXPECT_EQ(advertisement->vendor_id(),
static_cast<uint8_t>(Advertisement::BlockedVendorId::kSamsung));
}
TEST_F(NearbySharingServiceImplTest,
NoNetworkRegisterReceiveSurfaceIsAdvertising) {
MockTransferUpdateCallback callback;