mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Add vendor ID from a registered receive surface to the advertisement.
PiperOrigin-RevId: 639091253
This commit is contained in:
committed by
Copybara-Service
parent
5000f0a4d4
commit
ec3cf6ca26
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user