mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Implement Fast Pair discoverable scanner
PiperOrigin-RevId: 508484936
This commit is contained in:
committed by
Copybara-Service
parent
75feca580b
commit
5cb25a1a70
@@ -17,9 +17,12 @@ licenses(["notice"])
|
||||
cc_library(
|
||||
name = "scanning",
|
||||
srcs = [
|
||||
"fast_pair_discoverable_scanner_impl.cc",
|
||||
"fast_pair_scanner_impl.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"fast_pair_discoverable_scanner.h",
|
||||
"fast_pair_discoverable_scanner_impl.h",
|
||||
"fast_pair_scanner.h",
|
||||
"fast_pair_scanner_impl.h",
|
||||
],
|
||||
@@ -31,6 +34,9 @@ cc_library(
|
||||
"//fastpair/common",
|
||||
"//fastpair/dataparser",
|
||||
"//fastpair/internal/ble",
|
||||
"//fastpair/proto:fastpair_cc_proto",
|
||||
"//fastpair/repository",
|
||||
"//fastpair/server_access",
|
||||
"//internal/base",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:comm",
|
||||
@@ -63,3 +69,24 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "fast_pair_discoverable_scanner_impl_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"fast_pair_discoverable_scanner_impl_test.cc",
|
||||
],
|
||||
shard_count = 16,
|
||||
deps = [
|
||||
":scanning",
|
||||
"//fastpair/dataparser",
|
||||
"//fastpair/server_access:test_support",
|
||||
"//fastpair/testing",
|
||||
"//internal/platform:comm",
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_H_
|
||||
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "fastpair/common/fast_pair_device.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
using DeviceCallback = absl::AnyInvocable<void(FastPairDevice& device)>;
|
||||
|
||||
// This class detects Fast Pair 'discoverable' advertisements (see
|
||||
// https://developers.google.com/nearby/fast-pair/spec#AdvertisingWhenDiscoverable)
|
||||
// and invokes the |found_callback| when it finds a device within the
|
||||
// appropriate range. |lost_callback| will be invoked when that device is lost
|
||||
// to the bluetooth adapter.
|
||||
|
||||
class FastPairDiscoverableScanner {
|
||||
public:
|
||||
virtual ~FastPairDiscoverableScanner() = default;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_H_
|
||||
@@ -0,0 +1,213 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/functional/bind_front.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/common/constant.h"
|
||||
#include "fastpair/common/fast_pair_device.h"
|
||||
#include "fastpair/common/protocol.h"
|
||||
#include "fastpair/dataparser/fast_pair_data_parser.h"
|
||||
#include "fastpair/proto/fastpair_rpcs.pb.h"
|
||||
#include "fastpair/server_access/fast_pair_repository.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
namespace {
|
||||
constexpr char kNearbyShareModelId[] = "fc128e";
|
||||
|
||||
bool IsValidDeviceType(const proto::Device& device) {
|
||||
return device.device_type() == proto::DeviceType::HEADPHONES ||
|
||||
device.device_type() == proto::DeviceType::SPEAKER ||
|
||||
device.device_type() == proto::DeviceType::TRUE_WIRELESS_HEADPHONES ||
|
||||
device.device_type() == proto::DeviceType::DEVICE_TYPE_UNSPECIFIED;
|
||||
}
|
||||
|
||||
bool IsSupportedNotificationType(const proto::Device& device) {
|
||||
// We only allow-list notification types that should trigger a pairing
|
||||
// notification, since we currently only support pairing. We include
|
||||
// NOTIFICATION_TYPE_UNSPECIFIED to handle the case where a Provider is
|
||||
// advertising incorrectly and conservatively allow it to show a notification,
|
||||
// matching Android behavior.
|
||||
return device.notification_type() ==
|
||||
proto::NotificationType::NOTIFICATION_TYPE_UNSPECIFIED ||
|
||||
device.notification_type() == proto::NotificationType::FAST_PAIR ||
|
||||
device.notification_type() == proto::NotificationType::FAST_PAIR_ONE;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// FastPairScannerImpl::Factory
|
||||
FastPairDiscoverableScannerImpl::Factory*
|
||||
FastPairDiscoverableScannerImpl::Factory::g_test_factory_ = nullptr;
|
||||
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
std::shared_ptr<FastPairScanner> scanner,
|
||||
std::shared_ptr<BluetoothAdapter> adapter, DeviceCallback found_callback,
|
||||
DeviceCallback lost_callback) {
|
||||
if (g_test_factory_) {
|
||||
return g_test_factory_->CreateInstance(
|
||||
std::move(scanner), std::move(adapter), std::move(found_callback),
|
||||
std::move(lost_callback));
|
||||
}
|
||||
|
||||
return std::make_unique<FastPairDiscoverableScannerImpl>(
|
||||
std::move(scanner), std::move(adapter), std::move(found_callback),
|
||||
std::move(lost_callback));
|
||||
}
|
||||
|
||||
void FastPairDiscoverableScannerImpl::Factory::SetFactoryForTesting(
|
||||
Factory* g_test_factory) {
|
||||
g_test_factory_ = g_test_factory;
|
||||
}
|
||||
|
||||
FastPairDiscoverableScannerImpl::Factory::~Factory() = default;
|
||||
|
||||
// FastPairScannerImpl
|
||||
FastPairDiscoverableScannerImpl::FastPairDiscoverableScannerImpl(
|
||||
std::shared_ptr<FastPairScanner> scanner,
|
||||
std::shared_ptr<BluetoothAdapter> adapter, DeviceCallback found_callback,
|
||||
DeviceCallback lost_callback)
|
||||
: scanner_(std::move(scanner)),
|
||||
adapter_(std::move(adapter)),
|
||||
found_callback_(std::move(found_callback)),
|
||||
lost_callback_(std::move(lost_callback)) {
|
||||
scanner_->AddObserver(this);
|
||||
}
|
||||
|
||||
void FastPairDiscoverableScannerImpl::OnDeviceFound(
|
||||
const BlePeripheral& peripheral) {
|
||||
ByteArray fast_pair_service_data =
|
||||
peripheral.GetAdvertisementBytes(kServiceId);
|
||||
if (fast_pair_service_data.Empty()) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": Device doesn't have any Fast Pair Service Data.";
|
||||
return;
|
||||
}
|
||||
|
||||
model_id_parse_attempts_[peripheral.GetName()] = 1;
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": Attempting to get model ID";
|
||||
std::vector<uint8_t> service_data;
|
||||
std::string model_id_bytes = fast_pair_service_data.data();
|
||||
std::move(std::begin(model_id_bytes), std::end(model_id_bytes),
|
||||
std::back_inserter(service_data));
|
||||
|
||||
FastPairDataParser::GetHexModelIdFromServiceData(
|
||||
service_data,
|
||||
{[this, peripheral](absl::optional<absl::string_view> model_id) {
|
||||
OnModelIdRetrieved(peripheral.GetName(), model_id);
|
||||
}});
|
||||
}
|
||||
|
||||
void FastPairDiscoverableScannerImpl::OnModelIdRetrieved(
|
||||
const std::string& address,
|
||||
const absl::optional<absl::string_view> model_id) {
|
||||
auto it = model_id_parse_attempts_.find(address);
|
||||
|
||||
// If there's no entry in the map, the device was lost while parsing.
|
||||
if (it == model_id_parse_attempts_.end()) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< __func__
|
||||
<< ": Returning early because device as lost while parsing.";
|
||||
return;
|
||||
}
|
||||
|
||||
model_id_parse_attempts_.erase(it);
|
||||
|
||||
if (!model_id.has_value()) {
|
||||
NEARBY_LOGS(INFO) << __func__
|
||||
<< ": Returning early because no model id was parsed.";
|
||||
return;
|
||||
}
|
||||
|
||||
// The Nearby Share feature advertises under the Fast Pair Service Data UUID
|
||||
// and uses a reserved model ID to enable their 'fast initiation' scenario.
|
||||
// We must detect this instance and ignore these advertisements since they
|
||||
// do not correspond to Fast Pair devices that are open to pairing.
|
||||
if (model_id.value().compare(kNearbyShareModelId) == 0) {
|
||||
NEARBY_LOGS(WARNING) << __func__ << ": Ignore Nearby Share Model ID.";
|
||||
return;
|
||||
}
|
||||
|
||||
FastPairRepository::Get()->GetDeviceMetadata(
|
||||
model_id.value(),
|
||||
absl::bind_front(
|
||||
&FastPairDiscoverableScannerImpl::OnDeviceMetadataRetrieved, this,
|
||||
address, std::string(model_id.value())));
|
||||
}
|
||||
|
||||
void FastPairDiscoverableScannerImpl::OnDeviceMetadataRetrieved(
|
||||
const std::string& address, const std::string model_id,
|
||||
DeviceMetadata& device_metadata) {
|
||||
// Ignore advertisements that aren't for Fast Pair but leverage the service
|
||||
// UUID.
|
||||
if (!IsValidDeviceType(device_metadata.GetDetails())) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< __func__
|
||||
<< ": Invalid device type for Fast Pair. Ignoring this advertisement";
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore advertisements for unsupported notification types, such as
|
||||
// APP_LAUNCH which should launch a companion app instead of beginning Fast
|
||||
// Pair.
|
||||
if (!IsSupportedNotificationType(device_metadata.GetDetails())) {
|
||||
NEARBY_LOGS(WARNING) << __func__
|
||||
<< ": Unsupported notification type for Fast Pair. "
|
||||
"Ignoring this advertisement";
|
||||
return;
|
||||
}
|
||||
|
||||
FastPairDevice device(model_id, address, Protocol::kFastPairInitialPairing);
|
||||
NotifyDeviceFound(device);
|
||||
}
|
||||
|
||||
void FastPairDiscoverableScannerImpl::NotifyDeviceFound(
|
||||
FastPairDevice& device) {
|
||||
NEARBY_LOGS(VERBOSE) << "Notify Device found:"
|
||||
<< "BluetoothAddress = " << device.ble_address
|
||||
<< ", Model id = " << device.model_id;
|
||||
notified_devices_[device.ble_address] = &device;
|
||||
found_callback_(device);
|
||||
}
|
||||
|
||||
void FastPairDiscoverableScannerImpl::OnDeviceLost(
|
||||
const BlePeripheral& peripheral) {
|
||||
NEARBY_LOGS(INFO) << __func__ << ": Running lost callback";
|
||||
|
||||
model_id_parse_attempts_.erase(peripheral.GetName());
|
||||
|
||||
auto it = notified_devices_.find(peripheral.GetName());
|
||||
|
||||
// Don't invoke callback if we didn't notify this device.
|
||||
if (it == notified_devices_.end()) return;
|
||||
FastPairDevice* notified_device = it->second;
|
||||
notified_devices_.erase(it);
|
||||
lost_callback_(*notified_device);
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_IMPL_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_IMPL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fastpair/common/fast_pair_device.h"
|
||||
#include "fastpair/repository/device_metadata.h"
|
||||
#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner.h"
|
||||
#include "fastpair/scanning/fastpair/fast_pair_scanner.h"
|
||||
#include "internal/base/observer_list.h"
|
||||
#include "internal/platform/bluetooth_adapter.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class FastPairDiscoverableScannerImpl : public FastPairDiscoverableScanner,
|
||||
public FastPairScanner::Observer {
|
||||
public:
|
||||
class Factory {
|
||||
public:
|
||||
static std::unique_ptr<FastPairDiscoverableScanner> Create(
|
||||
std::shared_ptr<FastPairScanner> scanner,
|
||||
std::shared_ptr<BluetoothAdapter> adapter,
|
||||
DeviceCallback found_callback, DeviceCallback lost_callback);
|
||||
|
||||
static void SetFactoryForTesting(Factory* g_test_factory);
|
||||
|
||||
protected:
|
||||
virtual ~Factory();
|
||||
virtual std::unique_ptr<FastPairDiscoverableScanner> CreateInstance(
|
||||
std::shared_ptr<FastPairScanner> scanner,
|
||||
std::shared_ptr<BluetoothAdapter> adapter,
|
||||
DeviceCallback found_callback, DeviceCallback lost_callback) = 0;
|
||||
|
||||
private:
|
||||
static Factory* g_test_factory_;
|
||||
};
|
||||
|
||||
FastPairDiscoverableScannerImpl(std::shared_ptr<FastPairScanner> scanner,
|
||||
std::shared_ptr<BluetoothAdapter> adapter,
|
||||
DeviceCallback found_callback,
|
||||
DeviceCallback lost_callback);
|
||||
FastPairDiscoverableScannerImpl(const FastPairDiscoverableScannerImpl&) =
|
||||
delete;
|
||||
FastPairDiscoverableScannerImpl& operator=(
|
||||
const FastPairDiscoverableScannerImpl&) = delete;
|
||||
~FastPairDiscoverableScannerImpl() override = default;
|
||||
|
||||
// FastPairScanner::Observer
|
||||
void OnDeviceFound(const BlePeripheral& peripheral) override;
|
||||
void OnDeviceLost(const BlePeripheral& peripheral) override;
|
||||
|
||||
private:
|
||||
void OnModelIdRetrieved(const std::string& address,
|
||||
std::optional<absl::string_view> model_id);
|
||||
void OnDeviceMetadataRetrieved(const std::string& address,
|
||||
const std::string model_id,
|
||||
DeviceMetadata& device_metadata);
|
||||
void NotifyDeviceFound(FastPairDevice& device);
|
||||
|
||||
std::shared_ptr<FastPairScanner> scanner_;
|
||||
std::shared_ptr<BluetoothAdapter> adapter_;
|
||||
DeviceCallback found_callback_;
|
||||
DeviceCallback lost_callback_;
|
||||
absl::flat_hash_map<std::string, FastPairDevice*> notified_devices_;
|
||||
absl::flat_hash_map<std::string, int> model_id_parse_attempts_;
|
||||
ObserverList<FastPairScanner::Observer> observer_list_;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_SCANNING_FASTPAIR_FAST_PAIR_DISCOVERABLE_SCANNER_IMPL_H_
|
||||
@@ -0,0 +1,318 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "fastpair/scanning/fastpair/fast_pair_discoverable_scanner_impl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
#include "fastpair/scanning/fastpair/fast_pair_scanner_impl.h"
|
||||
#include "fastpair/server_access/fake_fast_pair_repository.h"
|
||||
#include "fastpair/testing/fast_pair_service_data_creator.h"
|
||||
#include "internal/platform/bluetooth_adapter.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
namespace {
|
||||
|
||||
constexpr absl::Duration kWaitTimeout = absl::Milliseconds(200);
|
||||
constexpr char kValidModelId[] = "718c17";
|
||||
constexpr char kInvalidModelId[] = "12345";
|
||||
constexpr char kNearbyShareModelId[] = "fc128e";
|
||||
constexpr char kTestBleDeviceAddress[] = "11:12:13:14:15:16";
|
||||
|
||||
class FakeBlePeripheral : public api::BlePeripheral {
|
||||
public:
|
||||
explicit FakeBlePeripheral(absl::string_view name,
|
||||
absl::string_view model_id) {
|
||||
name_ = std::string(name);
|
||||
const std::vector<uint8_t> service_data =
|
||||
FastPairServiceDataCreator::Builder()
|
||||
.SetModelId(std::string(model_id))
|
||||
.Build()
|
||||
->CreateServiceData();
|
||||
ByteArray advertisement_bytes(
|
||||
std::string(service_data.begin(), service_data.end()));
|
||||
advertisement_data_ = advertisement_bytes;
|
||||
}
|
||||
|
||||
FakeBlePeripheral(const FakeBlePeripheral&) = default;
|
||||
~FakeBlePeripheral() override = default;
|
||||
|
||||
std::string GetName() const override { return name_; }
|
||||
|
||||
ByteArray GetAdvertisementBytes(
|
||||
const std::string& service_id) const override {
|
||||
return advertisement_data_;
|
||||
}
|
||||
|
||||
void SetName(const std::string& name) { name_ = name; }
|
||||
|
||||
void SetAdvertisementBytes(ByteArray advertisement_bytes) {
|
||||
advertisement_data_ = advertisement_bytes;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
ByteArray advertisement_data_;
|
||||
};
|
||||
|
||||
class FastPairDiscoverableScannerImplTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
SetUpMetadata();
|
||||
scanner_ = std::make_shared<FastPairScannerImpl>();
|
||||
adapter_ = std::make_shared<BluetoothAdapter>();
|
||||
}
|
||||
|
||||
void SetUpMetadata() {
|
||||
repository_ = std::make_unique<FakeFastPairRepository>();
|
||||
proto::Device metadata;
|
||||
metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES);
|
||||
repository_->SetFakeMetadata(kValidModelId, metadata);
|
||||
}
|
||||
|
||||
// void TearDown() override { discoverable_scanner_.reset(); }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<FastPairScannerImpl> scanner_;
|
||||
std::unique_ptr<FakeFastPairRepository> repository_;
|
||||
std::shared_ptr<BluetoothAdapter> adapter_;
|
||||
DeviceCallback found_device_callback_;
|
||||
DeviceCallback lost_device_callback_;
|
||||
};
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, ValidModelId) {
|
||||
absl::Notification found_notification;
|
||||
absl::Notification lost_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
lost_device_callback_ = [&lost_notification](FastPairDevice& device) {
|
||||
lost_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->OnDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_TRUE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
scanner_->OnDeviceLost(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_TRUE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, InvalidModelId) {
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral = std::make_unique<FakeBlePeripheral>(
|
||||
kTestBleDeviceAddress, kInvalidModelId);
|
||||
scanner_->OnDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, NoServiceData) {
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, "");
|
||||
scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, UnsupportedDeviceType) {
|
||||
proto::Device metadata;
|
||||
metadata.set_device_type(proto::DeviceType::AUTOMOTIVE);
|
||||
repository_->SetFakeMetadata(kValidModelId, metadata);
|
||||
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, UnsupportedNotifictionType) {
|
||||
proto::Device metadata;
|
||||
metadata.set_device_type(proto::DeviceType::HEADPHONES);
|
||||
metadata.set_notification_type(proto::NotificationType::APP_LAUNCH);
|
||||
repository_->SetFakeMetadata(kValidModelId, metadata);
|
||||
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, UnspecifiedNotificationType) {
|
||||
// Set metadata to mimic a device that doesn't specify the notification
|
||||
// or device type. Since we aren't sure what this device is, we'll show
|
||||
// the notification to be safe.
|
||||
proto::Device metadata;
|
||||
metadata.set_device_type(proto::DeviceType::DEVICE_TYPE_UNSPECIFIED);
|
||||
metadata.set_notification_type(
|
||||
proto::NotificationType::NOTIFICATION_TYPE_UNSPECIFIED);
|
||||
repository_->SetFakeMetadata(kValidModelId, metadata);
|
||||
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_TRUE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, V1NotificationType) {
|
||||
// Set metadata to mimic a V1 device which advertises with no device
|
||||
// type and a notification type of FAST_PAIR_ONE.
|
||||
proto::Device metadata;
|
||||
metadata.set_device_type(proto::DeviceType::DEVICE_TYPE_UNSPECIFIED);
|
||||
metadata.set_notification_type(proto::NotificationType::FAST_PAIR_ONE);
|
||||
repository_->SetFakeMetadata(kValidModelId, metadata);
|
||||
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_TRUE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, V2NotificationType) {
|
||||
// Set metadata to mimic a V2 device which advertises with a device
|
||||
// type of TRUE_WIRELESS_HEADPHONES and a notification type of FAST_PAIR.
|
||||
proto::Device metadata;
|
||||
metadata.set_device_type(proto::DeviceType::TRUE_WIRELESS_HEADPHONES);
|
||||
metadata.set_notification_type(proto::NotificationType::FAST_PAIR);
|
||||
repository_->SetFakeMetadata(kValidModelId, metadata);
|
||||
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->NotifyDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_TRUE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest, NearbyShareModelId) {
|
||||
absl::Notification found_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral = std::make_unique<FakeBlePeripheral>(
|
||||
kTestBleDeviceAddress, kNearbyShareModelId);
|
||||
scanner_->OnDeviceFound(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_FALSE(found_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
TEST_F(FastPairDiscoverableScannerImplTest,
|
||||
DoesntInvokeLostCallbackIfDidntInvokeFound) {
|
||||
absl::Notification found_notification;
|
||||
absl::Notification lost_notification;
|
||||
found_device_callback_ = [&found_notification](FastPairDevice& device) {
|
||||
found_notification.Notify();
|
||||
};
|
||||
lost_device_callback_ = [&lost_notification](FastPairDevice& device) {
|
||||
lost_notification.Notify();
|
||||
};
|
||||
std::unique_ptr<FastPairDiscoverableScanner>
|
||||
discoverable_scanner_from_factory =
|
||||
FastPairDiscoverableScannerImpl::Factory::Create(
|
||||
scanner_, adapter_, std::move(found_device_callback_),
|
||||
std::move(lost_device_callback_));
|
||||
|
||||
auto ble_peripheral =
|
||||
std::make_unique<FakeBlePeripheral>(kTestBleDeviceAddress, kValidModelId);
|
||||
scanner_->OnDeviceLost(BlePeripheral(ble_peripheral.get()));
|
||||
EXPECT_FALSE(lost_notification.WaitForNotificationWithTimeout(kWaitTimeout));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user