Commit df6364f8 authored by Giovanni Ortuño Urquidi's avatar Giovanni Ortuño Urquidi Committed by Commit Bot

Revert "[CrOS MultiDevice] Add BleConnectionManager."

This reverts commit 1582e398.

Reason for revert: Broke chromeos_unittests

https://findit-for-me.appspot.com/waterfall/failure?redirect=1&url=https://ci.chromium.org/buildbot/chromium.memory/Linux%20Chromium%20OS%20ASan%20LSan%20Tests%20%281%29/27937

https://ci.chromium.org/buildbot/chromium.memory/Linux%20Chromium%20OS%20ASan%20LSan%20Tests%20%281%29/27937

Original change's description:
> [CrOS MultiDevice] Add BleConnectionManager.
> 
> Creates connections to remote devices over Bluetooth, using either the
> listener role (BLE scans only) or the initiator role (a combination of BLE
> advertising and scanning).
> 
> When a connection is attempted, it remains active until either an
> AuthenticatedChannel is returned successfully or until the request is
> explicitly removed via one of the Cancel*() functions.
> 
> Bug: 824568, 752273
> Change-Id: Icda1cde32e3d4455742c1570df15b82979cd0ace
> Reviewed-on: https://chromium-review.googlesource.com/1100133
> Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
> Reviewed-by: Ryan Hansberry <hansberry@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#567796}

TBR=khorimoto@chromium.org,hansberry@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 824568, 752273
Change-Id: Ie665ff0cc4390132955e4599eb3dab7caedd8746
Reviewed-on: https://chromium-review.googlesource.com/1103917Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Commit-Queue: Giovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567936}
parent 47a732b0
...@@ -18,10 +18,6 @@ static_library("secure_channel") { ...@@ -18,10 +18,6 @@ static_library("secure_channel") {
"ble_advertiser.h", "ble_advertiser.h",
"ble_advertiser_impl.cc", "ble_advertiser_impl.cc",
"ble_advertiser_impl.h", "ble_advertiser_impl.h",
"ble_connection_manager.cc",
"ble_connection_manager.h",
"ble_connection_manager_impl.cc",
"ble_connection_manager_impl.h",
"ble_constants.h", "ble_constants.h",
"ble_initiator_failure_type.cc", "ble_initiator_failure_type.cc",
"ble_initiator_failure_type.h", "ble_initiator_failure_type.h",
...@@ -133,8 +129,6 @@ static_library("test_support") { ...@@ -133,8 +129,6 @@ static_library("test_support") {
"fake_active_connection_manager.h", "fake_active_connection_manager.h",
"fake_ble_advertiser.cc", "fake_ble_advertiser.cc",
"fake_ble_advertiser.h", "fake_ble_advertiser.h",
"fake_ble_connection_manager.cc",
"fake_ble_connection_manager.h",
"fake_ble_scanner.cc", "fake_ble_scanner.cc",
"fake_ble_scanner.h", "fake_ble_scanner.h",
"fake_ble_service_data_helper.cc", "fake_ble_service_data_helper.cc",
...@@ -193,7 +187,6 @@ source_set("unit_tests") { ...@@ -193,7 +187,6 @@ source_set("unit_tests") {
"active_connection_manager_impl_unittest.cc", "active_connection_manager_impl_unittest.cc",
"authenticated_channel_impl_unittest.cc", "authenticated_channel_impl_unittest.cc",
"ble_advertiser_impl_unittest.cc", "ble_advertiser_impl_unittest.cc",
"ble_connection_manager_impl_unittest.cc",
"ble_initiator_operation_unittest.cc", "ble_initiator_operation_unittest.cc",
"ble_listener_operation_unittest.cc", "ble_listener_operation_unittest.cc",
"ble_scanner_impl_unittest.cc", "ble_scanner_impl_unittest.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/services/secure_channel/ble_connection_manager.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
#include "chromeos/services/secure_channel/public/cpp/shared/authenticated_channel.h"
#include "components/cryptauth/remote_device_ref.h"
namespace chromeos {
namespace secure_channel {
BleConnectionManager::InitiatorConnectionAttemptMetadata::
InitiatorConnectionAttemptMetadata(
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleInitiatorFailureCallback& failure_callback)
: connection_priority(connection_priority),
success_callback(std::move(success_callback)),
failure_callback(failure_callback) {}
BleConnectionManager::InitiatorConnectionAttemptMetadata::
~InitiatorConnectionAttemptMetadata() = default;
BleConnectionManager::ListenerConnectionAttemptMetadata::
ListenerConnectionAttemptMetadata(
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleListenerFailureCallback& failure_callback)
: connection_priority(connection_priority),
success_callback(std::move(success_callback)),
failure_callback(failure_callback) {}
BleConnectionManager::ListenerConnectionAttemptMetadata::
~ListenerConnectionAttemptMetadata() = default;
BleConnectionManager::BleConnectionManager() = default;
BleConnectionManager::~BleConnectionManager() = default;
void BleConnectionManager::AttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleInitiatorFailureCallback& failure_callback) {
if (base::ContainsKey(id_pair_to_initiator_metadata_map_, device_id_pair)) {
PA_LOG(ERROR) << "BleConnectionManager::AttemptBleInitiatorConnection(): "
<< "Tried to add BLE initiator connection attempt, but one "
<< "was already active. Device IDs: " << device_id_pair
<< ", Priority: " << connection_priority;
NOTREACHED();
}
ConnectionAttemptDetails details(device_id_pair,
ConnectionMedium::kBluetoothLowEnergy,
ConnectionRole::kInitiatorRole);
remote_device_id_to_details_map_[device_id_pair.remote_device_id()].insert(
details);
id_pair_to_initiator_metadata_map_.emplace(std::make_pair(
device_id_pair,
std::make_unique<InitiatorConnectionAttemptMetadata>(
connection_priority, std::move(success_callback), failure_callback)));
PA_LOG(INFO) << "BleConnectionManager::AttemptBleInitiatorConnection(): "
<< "Attempting connection; details: " << details;
PerformAttemptBleInitiatorConnection(device_id_pair, connection_priority);
}
void BleConnectionManager::UpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {
auto& initiator_entry = GetInitiatorEntry(device_id_pair);
if (initiator_entry.connection_priority == connection_priority) {
PA_LOG(WARNING) << "BleConnectionManager::"
<< "UpdateBleInitiatorConnectionPriority(): "
<< "Tried to update BLE initiator connection attempt, but "
<< "the provided priority was the same as the previous "
<< "priority. Device IDs: " << device_id_pair
<< ", Priority: " << connection_priority;
return;
}
initiator_entry.connection_priority = connection_priority;
PA_LOG(INFO) << "BleConnectionManager::"
<< "UpdateBleInitiatorConnectionPriority(): Updating connection "
<< "priority; ID pair: " << device_id_pair
<< ", Priority: " << connection_priority;
PerformUpdateBleInitiatorConnectionPriority(device_id_pair,
connection_priority);
}
void BleConnectionManager::CancelBleInitiatorConnectionAttempt(
const DeviceIdPair& device_id_pair) {
RemoveRequestMetadata(device_id_pair, ConnectionRole::kInitiatorRole);
PA_LOG(INFO) << "BleConnectionManager::"
<< "CancelBleInitiatorConnectionAttempt(): Canceling connection "
<< "attempt; ID pair: " << device_id_pair;
PerformCancelBleInitiatorConnectionAttempt(device_id_pair);
}
void BleConnectionManager::AttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleListenerFailureCallback& failure_callback) {
if (base::ContainsKey(id_pair_to_listener_metadata_map_, device_id_pair)) {
PA_LOG(ERROR) << "BleConnectionManager::AttemptBleListenerConnection(): "
<< "Tried to add BLE listener connection attempt, but one "
<< "was already active. Device IDs: " << device_id_pair
<< ", Priority: " << connection_priority;
NOTREACHED();
}
ConnectionAttemptDetails details(device_id_pair,
ConnectionMedium::kBluetoothLowEnergy,
ConnectionRole::kListenerRole);
remote_device_id_to_details_map_[device_id_pair.remote_device_id()].insert(
details);
id_pair_to_listener_metadata_map_.emplace(std::make_pair(
device_id_pair,
std::make_unique<ListenerConnectionAttemptMetadata>(
connection_priority, std::move(success_callback), failure_callback)));
PA_LOG(INFO) << "BleConnectionManager::AttemptBleListenerConnection(): "
<< "Attempting connection; details: " << details;
PerformAttemptBleListenerConnection(device_id_pair, connection_priority);
}
void BleConnectionManager::UpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {
auto& listener_entry = GetListenerEntry(device_id_pair);
if (listener_entry.connection_priority == connection_priority) {
PA_LOG(WARNING) << "BleConnectionManager::"
<< "UpdateBleListenerConnectionPriority(): "
<< "Tried to update BLE listener connection attempt, but "
<< "the provided priority was the same as the previous "
<< "priority. Device IDs: " << device_id_pair
<< ", Priority: " << connection_priority;
return;
}
listener_entry.connection_priority = connection_priority;
PA_LOG(INFO) << "BleConnectionManager::"
<< "UpdateBleListenerConnectionPriority(): Updating connection "
<< "priority; ID pair: " << device_id_pair << ", Priority"
<< connection_priority;
PerformUpdateBleListenerConnectionPriority(device_id_pair,
connection_priority);
}
void BleConnectionManager::CancelBleListenerConnectionAttempt(
const DeviceIdPair& device_id_pair) {
RemoveRequestMetadata(device_id_pair, ConnectionRole::kListenerRole);
PA_LOG(INFO) << "BleConnectionManager::"
<< "CancelBleListenerConnectionAttempt(): Canceling connection "
<< "attempt; ID pair: " << device_id_pair;
PerformCancelBleListenerConnectionAttempt(device_id_pair);
}
ConnectionPriority BleConnectionManager::GetPriorityForAttempt(
const DeviceIdPair& device_id_pair,
ConnectionRole connection_role) {
switch (connection_role) {
case ConnectionRole::kInitiatorRole:
return GetInitiatorEntry(device_id_pair).connection_priority;
case ConnectionRole::kListenerRole:
return GetListenerEntry(device_id_pair).connection_priority;
}
}
const base::flat_set<ConnectionAttemptDetails>&
BleConnectionManager::GetDetailsForRemoteDevice(
const std::string& remote_device_id) {
if (!base::ContainsKey(remote_device_id_to_details_map_, remote_device_id)) {
PA_LOG(ERROR) << "BleConnectionManager::GetDetailsForRemoteDevice(): Tried "
<< "to get details for a remote device, but no device with "
<< "the provided ID existed. ID: "
<< cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs(
remote_device_id);
NOTREACHED();
}
return remote_device_id_to_details_map_[remote_device_id];
}
bool BleConnectionManager::DoesAttemptExist(const DeviceIdPair& device_id_pair,
ConnectionRole connection_role) {
switch (connection_role) {
case ConnectionRole::kInitiatorRole:
return base::ContainsKey(id_pair_to_initiator_metadata_map_,
device_id_pair);
case ConnectionRole::kListenerRole:
return base::ContainsKey(id_pair_to_listener_metadata_map_,
device_id_pair);
}
}
void BleConnectionManager::NotifyBleInitiatorFailure(
const DeviceIdPair& device_id_pair,
BleInitiatorFailureType failure_type) {
PA_LOG(INFO) << "BleConnectionManager::NotifyBleInitiatorFailure(): "
<< "Notifying client of failure. ID pair: " << device_id_pair
<< ", Failure type: " << failure_type;
GetInitiatorEntry(device_id_pair).failure_callback.Run(failure_type);
}
void BleConnectionManager::NotifyBleListenerFailure(
const DeviceIdPair& device_id_pair,
BleListenerFailureType failure_type) {
PA_LOG(INFO) << "BleConnectionManager::NotifyBleListenerFailure(): "
<< "Notifying client of failure. ID pair: " << device_id_pair
<< ", Failure type: " << failure_type;
GetListenerEntry(device_id_pair).failure_callback.Run(failure_type);
}
void BleConnectionManager::NotifyConnectionSuccess(
const DeviceIdPair& device_id_pair,
ConnectionRole connection_role,
std::unique_ptr<AuthenticatedChannel> authenticated_channel) {
PA_LOG(INFO) << "BleConnectionManager::NotifyConnectionSuccess(): "
<< "Notifying client of successful connection. ID pair: "
<< device_id_pair << ", Role: " << connection_role;
// For each case, grab the success callback out of the map first, then remove
// the associated metadata before invoking the callback.
switch (connection_role) {
case ConnectionRole::kInitiatorRole: {
ConnectionSuccessCallback success_callback =
std::move(GetInitiatorEntry(device_id_pair).success_callback);
RemoveRequestMetadata(device_id_pair, ConnectionRole::kInitiatorRole);
std::move(success_callback).Run(std::move(authenticated_channel));
break;
}
case ConnectionRole::kListenerRole: {
ConnectionSuccessCallback success_callback =
std::move(GetListenerEntry(device_id_pair).success_callback);
RemoveRequestMetadata(device_id_pair, ConnectionRole::kListenerRole);
std::move(success_callback).Run(std::move(authenticated_channel));
break;
}
}
}
BleConnectionManager::InitiatorConnectionAttemptMetadata&
BleConnectionManager::GetInitiatorEntry(const DeviceIdPair& device_id_pair) {
if (!base::ContainsKey(id_pair_to_initiator_metadata_map_, device_id_pair)) {
PA_LOG(ERROR) << "BleConnectionManager::GetInitiatorEntry(): Tried to get "
<< "map entry, but it did not exist. Device IDs: "
<< device_id_pair;
NOTREACHED();
}
std::unique_ptr<InitiatorConnectionAttemptMetadata>& entry =
id_pair_to_initiator_metadata_map_[device_id_pair];
DCHECK(entry);
return *entry;
}
BleConnectionManager::ListenerConnectionAttemptMetadata&
BleConnectionManager::GetListenerEntry(const DeviceIdPair& device_id_pair) {
if (!base::ContainsKey(id_pair_to_listener_metadata_map_, device_id_pair)) {
PA_LOG(ERROR) << "BleConnectionManager::GetListenerEntry(): Tried to get "
<< "map entry, but it did not exist. Device IDs: "
<< device_id_pair;
NOTREACHED();
}
std::unique_ptr<ListenerConnectionAttemptMetadata>& entry =
id_pair_to_listener_metadata_map_[device_id_pair];
DCHECK(entry);
return *entry;
}
void BleConnectionManager::RemoveRequestMetadata(
const DeviceIdPair& device_id_pair,
ConnectionRole connection_role) {
switch (connection_role) {
case ConnectionRole::kInitiatorRole:
if (!base::ContainsKey(id_pair_to_initiator_metadata_map_,
device_id_pair)) {
PA_LOG(ERROR) << "BleConnectionManager::RemoveRequestMetadata(): Tried "
<< "to remove BLE initiator attempt, but no attempt "
<< "existed. Device IDs: " << device_id_pair;
NOTREACHED();
}
id_pair_to_initiator_metadata_map_.erase(device_id_pair);
break;
case ConnectionRole::kListenerRole:
if (!base::ContainsKey(id_pair_to_listener_metadata_map_,
device_id_pair)) {
PA_LOG(ERROR) << "BleConnectionManager::RemoveRequestMetadata(): Tried "
<< "to remove BLE listener attempt, but no attempt "
<< "existed. Device IDs: " << device_id_pair;
NOTREACHED();
}
id_pair_to_listener_metadata_map_.erase(device_id_pair);
break;
}
ConnectionAttemptDetails details(
device_id_pair, ConnectionMedium::kBluetoothLowEnergy, connection_role);
size_t num_removed =
remote_device_id_to_details_map_[device_id_pair.remote_device_id()].erase(
details);
if (num_removed != 1u) {
PA_LOG(ERROR) << "BleConnectionManager::RemoveRequestMetadata(): Tried "
<< "to remove connection attempt, but no remote device ID "
<< "entry existed. Device IDs: " << device_id_pair;
NOTREACHED();
}
}
} // namespace secure_channel
} // namespace chromeos
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_CONNECTION_MANAGER_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_CONNECTION_MANAGER_H_
#include <memory>
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "chromeos/services/secure_channel/ble_initiator_failure_type.h"
#include "chromeos/services/secure_channel/ble_listener_failure_type.h"
#include "chromeos/services/secure_channel/connection_attempt_details.h"
#include "chromeos/services/secure_channel/connection_role.h"
#include "chromeos/services/secure_channel/device_id_pair.h"
#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
namespace chromeos {
namespace secure_channel {
class AuthenticatedChannel;
// Creates connections to remote devices over Bluetooth, using either the
// listener role (BLE scans only) or the initiator role (a combination of BLE
// advertising and scanning).
//
// When a connection is attempted, it remains active until either an
// AuthenticatedChannel is returned successfully or until the request is
// explicitly removed via one of the Cancel*() functions.
//
// When a failure occurs, the client is notified, but the connection attempt
// remains active. This ensures that when attempts are retried after a failure,
// this class does not need to internally stop and then restart
// scanning/advertising.
class BleConnectionManager {
public:
virtual ~BleConnectionManager();
using ConnectionSuccessCallback =
base::OnceCallback<void(std::unique_ptr<AuthenticatedChannel>)>;
using BleInitiatorFailureCallback =
base::RepeatingCallback<void(BleInitiatorFailureType)>;
using BleListenerFailureCallback =
base::RepeatingCallback<void(BleListenerFailureType)>;
void AttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleInitiatorFailureCallback& failure_callback);
void UpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority);
void CancelBleInitiatorConnectionAttempt(const DeviceIdPair& device_id_pair);
void AttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleListenerFailureCallback& failure_callback);
void UpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority);
void CancelBleListenerConnectionAttempt(const DeviceIdPair& device_id_pair);
protected:
BleConnectionManager();
virtual void PerformAttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) = 0;
virtual void PerformUpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) = 0;
virtual void PerformCancelBleInitiatorConnectionAttempt(
const DeviceIdPair& device_id_pair) = 0;
virtual void PerformAttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) = 0;
virtual void PerformUpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) = 0;
virtual void PerformCancelBleListenerConnectionAttempt(
const DeviceIdPair& device_id_pair) = 0;
ConnectionPriority GetPriorityForAttempt(const DeviceIdPair& device_id_pair,
ConnectionRole connection_role);
const base::flat_set<ConnectionAttemptDetails>& GetDetailsForRemoteDevice(
const std::string& remote_device_id);
bool DoesAttemptExist(const DeviceIdPair& device_id_pair,
ConnectionRole connection_role);
void NotifyBleInitiatorFailure(const DeviceIdPair& device_id_pair,
BleInitiatorFailureType failure_type);
void NotifyBleListenerFailure(const DeviceIdPair& device_id_pair,
BleListenerFailureType failure_type);
void NotifyConnectionSuccess(
const DeviceIdPair& device_id_pair,
ConnectionRole connection_role,
std::unique_ptr<AuthenticatedChannel> authenticated_channel);
private:
struct InitiatorConnectionAttemptMetadata {
InitiatorConnectionAttemptMetadata(
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleInitiatorFailureCallback& failure_callback);
~InitiatorConnectionAttemptMetadata();
ConnectionPriority connection_priority;
ConnectionSuccessCallback success_callback;
BleInitiatorFailureCallback failure_callback;
};
struct ListenerConnectionAttemptMetadata {
ListenerConnectionAttemptMetadata(
ConnectionPriority connection_priority,
ConnectionSuccessCallback success_callback,
const BleListenerFailureCallback& failure_callback);
~ListenerConnectionAttemptMetadata();
ConnectionPriority connection_priority;
ConnectionSuccessCallback success_callback;
BleListenerFailureCallback failure_callback;
};
InitiatorConnectionAttemptMetadata& GetInitiatorEntry(
const DeviceIdPair& device_id_pair);
ListenerConnectionAttemptMetadata& GetListenerEntry(
const DeviceIdPair& device_id_pair);
void RemoveRequestMetadata(const DeviceIdPair& device_id_pair,
ConnectionRole connection_role);
base::flat_map<std::string, base::flat_set<ConnectionAttemptDetails>>
remote_device_id_to_details_map_;
base::flat_map<DeviceIdPair,
std::unique_ptr<InitiatorConnectionAttemptMetadata>>
id_pair_to_initiator_metadata_map_;
base::flat_map<DeviceIdPair,
std::unique_ptr<ListenerConnectionAttemptMetadata>>
id_pair_to_listener_metadata_map_;
DISALLOW_COPY_AND_ASSIGN(BleConnectionManager);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_CONNECTION_MANAGER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/services/secure_channel/ble_connection_manager_impl.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
#include "chromeos/services/secure_channel/authenticated_channel_impl.h"
#include "chromeos/services/secure_channel/ble_advertiser_impl.h"
#include "chromeos/services/secure_channel/ble_constants.h"
#include "chromeos/services/secure_channel/ble_initiator_failure_type.h"
#include "chromeos/services/secure_channel/ble_listener_failure_type.h"
#include "chromeos/services/secure_channel/ble_scanner_impl.h"
#include "chromeos/services/secure_channel/ble_synchronizer.h"
#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
#include "chromeos/services/secure_channel/secure_channel_disconnector_impl.h"
#include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h"
#include "device/bluetooth/bluetooth_uuid.h"
namespace chromeos {
namespace secure_channel {
namespace {
std::vector<mojom::ConnectionCreationDetail> CreateConnectionDetails(
ConnectionRole connection_role) {
std::vector<mojom::ConnectionCreationDetail> creation_details;
switch (connection_role) {
case ConnectionRole::kInitiatorRole:
creation_details.push_back(
mojom::ConnectionCreationDetail::
REMOTE_DEVICE_USED_FOREGROUND_BLE_ADVERTISING);
break;
case ConnectionRole::kListenerRole:
creation_details.push_back(
mojom::ConnectionCreationDetail::
REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING);
break;
}
return creation_details;
}
} // namespace
// static
BleConnectionManagerImpl::Factory*
BleConnectionManagerImpl::Factory::test_factory_ = nullptr;
// static
BleConnectionManagerImpl::Factory* BleConnectionManagerImpl::Factory::Get() {
if (test_factory_)
return test_factory_;
static base::NoDestructor<Factory> factory;
return factory.get();
}
// static
void BleConnectionManagerImpl::Factory::SetFactoryForTesting(
Factory* test_factory) {
test_factory_ = test_factory;
}
BleConnectionManagerImpl::Factory::~Factory() = default;
std::unique_ptr<BleConnectionManager>
BleConnectionManagerImpl::Factory::BuildInstance(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter,
BleServiceDataHelper* ble_service_data_helper,
TimerFactory* timer_factory) {
return base::WrapUnique(new BleConnectionManagerImpl(
bluetooth_adapter, ble_service_data_helper, timer_factory));
}
BleConnectionManagerImpl::BleConnectionManagerImpl(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter,
BleServiceDataHelper* ble_service_data_helper,
TimerFactory* timer_factory)
: bluetooth_adapter_(bluetooth_adapter),
ble_service_data_helper_(ble_service_data_helper),
ble_synchronizer_(
BleSynchronizer::Factory::Get()->BuildInstance(bluetooth_adapter)),
ble_advertiser_(BleAdvertiserImpl::Factory::Get()->BuildInstance(
this /* delegate */,
ble_service_data_helper_,
ble_synchronizer_.get(),
timer_factory)),
ble_scanner_(BleScannerImpl::Factory::Get()->BuildInstance(
this /* delegate */,
ble_service_data_helper_,
ble_synchronizer_.get(),
bluetooth_adapter)),
secure_channel_disconnector_(
SecureChannelDisconnectorImpl::Factory::Get()->BuildInstance()) {}
BleConnectionManagerImpl::~BleConnectionManagerImpl() = default;
void BleConnectionManagerImpl::PerformAttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {
if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id()))
return;
ble_advertiser_->AddAdvertisementRequest(device_id_pair, connection_priority);
ble_scanner_->AddScanFilter(
BleScanner::ScanFilter(device_id_pair, ConnectionRole::kInitiatorRole));
}
void BleConnectionManagerImpl::PerformUpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {
if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id()))
return;
ble_advertiser_->UpdateAdvertisementRequestPriority(device_id_pair,
connection_priority);
}
void BleConnectionManagerImpl::PerformCancelBleInitiatorConnectionAttempt(
const DeviceIdPair& device_id_pair) {
if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id())) {
// Check to see if we are removing the final request for an active channel;
// if so, that channel needs to be disconnected.
ProcessPotentialLingeringChannel(device_id_pair.remote_device_id());
return;
}
// If a client canceled its request as a result of being notified of an
// authenticated channel, that request was not actually active.
if (notifying_remote_device_id_ == device_id_pair.remote_device_id())
return;
ble_advertiser_->RemoveAdvertisementRequest(device_id_pair);
ble_scanner_->RemoveScanFilter(
BleScanner::ScanFilter(device_id_pair, ConnectionRole::kInitiatorRole));
}
void BleConnectionManagerImpl::PerformAttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {
if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id()))
return;
ble_scanner_->AddScanFilter(
BleScanner::ScanFilter(device_id_pair, ConnectionRole::kListenerRole));
}
void BleConnectionManagerImpl::PerformUpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {
// BLE scans are not prioritized, so nothing needs to be done.
}
void BleConnectionManagerImpl::PerformCancelBleListenerConnectionAttempt(
const DeviceIdPair& device_id_pair) {
if (DoesAuthenticatingChannelExist(device_id_pair.remote_device_id())) {
// Check to see if we are removing the final request for an active channel;
// if so, that channel needs to be disconnected.
ProcessPotentialLingeringChannel(device_id_pair.remote_device_id());
return;
}
// If a client canceled its request as a result of being notified of an
// authenticated channel, that request was not actually active.
if (notifying_remote_device_id_ == device_id_pair.remote_device_id())
return;
ble_scanner_->RemoveScanFilter(
BleScanner::ScanFilter(device_id_pair, ConnectionRole::kListenerRole));
}
void BleConnectionManagerImpl::OnAdvertisingSlotEnded(
const DeviceIdPair& device_id_pair,
bool replaced_by_higher_priority_advertisement) {
NotifyBleInitiatorFailure(
device_id_pair,
replaced_by_higher_priority_advertisement
? BleInitiatorFailureType::
kInterruptedByHigherPriorityConnectionAttempt
: BleInitiatorFailureType::kTimeoutContactingRemoteDevice);
}
void BleConnectionManagerImpl::OnReceivedAdvertisement(
cryptauth::RemoteDeviceRef remote_device,
device::BluetoothDevice* bluetooth_device,
ConnectionRole connection_role) {
// Create a connection to the device.
std::unique_ptr<cryptauth::Connection> connection =
cryptauth::weave::BluetoothLowEnergyWeaveClientConnection::Factory::
NewInstance(remote_device, bluetooth_adapter_,
device::BluetoothUUID(kGattServerUuid), bluetooth_device,
false /* should_set_low_connection_latency */);
SetAuthenticatingChannel(
remote_device.GetDeviceId(),
cryptauth::SecureChannel::Factory::NewInstance(std::move(connection)),
connection_role);
}
void BleConnectionManagerImpl::OnSecureChannelStatusChanged(
cryptauth::SecureChannel* secure_channel,
const cryptauth::SecureChannel::Status& old_status,
const cryptauth::SecureChannel::Status& new_status) {
std::string remote_device_id =
GetRemoteDeviceIdForSecureChannel(secure_channel);
if (new_status == cryptauth::SecureChannel::Status::DISCONNECTED) {
HandleSecureChannelDisconnection(
remote_device_id,
old_status == cryptauth::SecureChannel::Status::AUTHENTICATING
/* was_authenticating */);
return;
}
if (new_status == cryptauth::SecureChannel::Status::AUTHENTICATED) {
HandleChannelAuthenticated(remote_device_id);
return;
}
}
bool BleConnectionManagerImpl::DoesAuthenticatingChannelExist(
const std::string& remote_device_id) {
return base::ContainsKey(remote_device_id_to_secure_channel_map_,
remote_device_id);
}
void BleConnectionManagerImpl::SetAuthenticatingChannel(
const std::string& remote_device_id,
std::unique_ptr<cryptauth::SecureChannel> secure_channel,
ConnectionRole connection_role) {
// Since a channel has been established, all connection attempts to the device
// should be stopped. Otherwise, it would be possible to pick up additional
// scan results and try to start a new connection. Multiple simultaneous BLE
// connections to the same device can interfere with each other.
PauseConnectionAttemptsToDevice(remote_device_id);
// Observe the channel to be notified of when either the channel authenticates
// successfully or faces BLE instability and disconnects.
secure_channel->AddObserver(this);
if (base::ContainsKey(remote_device_id_to_secure_channel_map_,
remote_device_id)) {
PA_LOG(ERROR) << "BleConnectionManager::OnReceivedAdvertisement(): A new "
<< "channel was created, one already exists for the same "
<< "remote device ID. ID: "
<< cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs(
remote_device_id);
NOTREACHED();
}
PA_LOG(INFO) << "BleConnectionManager::OnReceivedAdvertisement(): Connection "
<< "established; starting authentication process. Remote device "
<< "ID: "
<< cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs(
remote_device_id)
<< ", Connection role: " << connection_role;
remote_device_id_to_secure_channel_map_[remote_device_id] =
std::make_pair(std::move(secure_channel), connection_role);
}
void BleConnectionManagerImpl::PauseConnectionAttemptsToDevice(
const std::string& remote_device_id) {
for (const auto& details : GetDetailsForRemoteDevice(remote_device_id)) {
switch (details.connection_role()) {
case ConnectionRole::kInitiatorRole:
PerformCancelBleInitiatorConnectionAttempt(details.device_id_pair());
break;
case ConnectionRole::kListenerRole:
PerformCancelBleListenerConnectionAttempt(details.device_id_pair());
break;
}
}
}
void BleConnectionManagerImpl::RestartPausedAttemptsToDevice(
const std::string& remote_device_id) {
for (const auto& details : GetDetailsForRemoteDevice(remote_device_id)) {
ConnectionPriority connection_priority = GetPriorityForAttempt(
details.device_id_pair(), details.connection_role());
switch (details.connection_role()) {
case ConnectionRole::kInitiatorRole:
PerformAttemptBleInitiatorConnection(details.device_id_pair(),
connection_priority);
break;
case ConnectionRole::kListenerRole:
PerformAttemptBleListenerConnection(details.device_id_pair(),
connection_priority);
break;
}
}
}
void BleConnectionManagerImpl::ProcessPotentialLingeringChannel(
const std::string& remote_device_id) {
// If there was no authenticating SecureChannel associated with
// |remote_device_id|, return early.
if (!base::ContainsKey(remote_device_id_to_secure_channel_map_,
remote_device_id)) {
return;
}
// If there is at least one active request, the channel should remain active.
if (!GetDetailsForRemoteDevice(remote_device_id).empty())
return;
// Extract the map value and remove the entry from the map.
SecureChannelWithRole channel_with_roll =
std::move(remote_device_id_to_secure_channel_map_[remote_device_id]);
remote_device_id_to_secure_channel_map_.erase(remote_device_id);
// Disconnect the channel, since it is lingering with no active request.
PA_LOG(INFO) << "BleConnectionManagerImpl::"
<< "ProcessPotentialLingeringChannel(): Disconnecting lingering "
<< "channel which is no longer associated with any active "
<< "requests. Remote device ID: "
<< cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs(
remote_device_id);
channel_with_roll.first->RemoveObserver(this);
secure_channel_disconnector_->DisconnectSecureChannel(
std::move(channel_with_roll.first));
}
std::string BleConnectionManagerImpl::GetRemoteDeviceIdForSecureChannel(
cryptauth::SecureChannel* secure_channel) {
for (const auto& map_entry : remote_device_id_to_secure_channel_map_) {
if (map_entry.second.first.get() == secure_channel)
return map_entry.first;
}
PA_LOG(ERROR) << "BleConnectionManager::GetRemoteDeviceIdForSecureChannel(): "
<< "No remote device ID mapped to the provided SecureChannel. ";
NOTREACHED();
return std::string();
}
void BleConnectionManagerImpl::HandleSecureChannelDisconnection(
const std::string& remote_device_id,
bool was_authenticating) {
for (const auto& details : GetDetailsForRemoteDevice(remote_device_id)) {
switch (details.connection_role()) {
// Initiator role devices are notified of authentication errors as well as
// GATT instability errors.
case ConnectionRole::kInitiatorRole:
NotifyBleInitiatorFailure(
details.device_id_pair(),
was_authenticating ? BleInitiatorFailureType::kAuthenticationError
: BleInitiatorFailureType::kGattConnectionError);
break;
// Listener role devices are only notified of authentication errors.
case ConnectionRole::kListenerRole:
if (was_authenticating) {
NotifyBleListenerFailure(
details.device_id_pair(),
BleListenerFailureType::kAuthenticationError);
}
break;
}
}
// Stop observer the disconnected channel and remove it from the map.
remote_device_id_to_secure_channel_map_[remote_device_id]
.first->RemoveObserver(this);
remote_device_id_to_secure_channel_map_.erase(remote_device_id);
// Since the previous connection failed, the connection attempts that were
// paused in SetAuthenticatingChannel() need to be started up again. Note
// that it is possible that clients handled being notified of the GATT failure
// above by removing the connection request due to too many failures.
RestartPausedAttemptsToDevice(remote_device_id);
}
void BleConnectionManagerImpl::HandleChannelAuthenticated(
const std::string& remote_device_id) {
// Extract the map value and remove the entry from the map.
SecureChannelWithRole channel_with_role =
std::move(remote_device_id_to_secure_channel_map_[remote_device_id]);
remote_device_id_to_secure_channel_map_.erase(remote_device_id);
// Stop observing the channel; it is about to be passed to a client.
channel_with_role.first->RemoveObserver(this);
ConnectionAttemptDetails channel_to_receive =
ChooseChannelRecipient(remote_device_id, channel_with_role.second);
// Before notifying clients, set |notifying_remote_device_id_|. This ensure
// that the PerformCancel*() functions can check to see whether requests need
// to be removed from BleScanner/BleAdvertiser.
notifying_remote_device_id_ = remote_device_id;
NotifyConnectionSuccess(
channel_to_receive.device_id_pair(), channel_to_receive.connection_role(),
AuthenticatedChannelImpl::Factory::Get()->BuildInstance(
CreateConnectionDetails(channel_with_role.second),
std::move(channel_with_role.first)));
notifying_remote_device_id_.reset();
// Restart any attempts which still exist.
RestartPausedAttemptsToDevice(remote_device_id);
}
ConnectionAttemptDetails BleConnectionManagerImpl::ChooseChannelRecipient(
const std::string& remote_device_id,
ConnectionRole connection_role) {
// More than one connection attempt could correspond to this channel. If so,
// arbitrarily choose the first one as the recipient of the authenticated
// channel.
for (const auto& details : GetDetailsForRemoteDevice(remote_device_id)) {
// Initiator role corresponds to foreground advertisements.
if (details.connection_role() == ConnectionRole::kInitiatorRole &&
connection_role == ConnectionRole::kInitiatorRole) {
return details;
}
// Listener role corresponds to background advertisements.
if (details.connection_role() == ConnectionRole::kListenerRole &&
connection_role == ConnectionRole::kListenerRole) {
return details;
}
}
PA_LOG(ERROR) << "BleConnectionManager::ChooseChannelRecipient(): Could not "
<< "find DeviceIdPair to receive channel. Remote device ID: "
<< cryptauth::RemoteDeviceRef::TruncateDeviceIdForLogs(
remote_device_id)
<< ", Role: " << connection_role;
NOTREACHED();
return ConnectionAttemptDetails(std::string(), std::string(),
ConnectionMedium::kBluetoothLowEnergy,
ConnectionRole::kInitiatorRole);
}
} // namespace secure_channel
} // namespace chromeos
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_CONNECTION_MANAGER_IMPL_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_CONNECTION_MANAGER_IMPL_H_
#include <memory>
#include <utility>
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "chromeos/services/secure_channel/ble_advertiser.h"
#include "chromeos/services/secure_channel/ble_connection_manager.h"
#include "chromeos/services/secure_channel/ble_scanner.h"
#include "chromeos/services/secure_channel/connection_role.h"
#include "chromeos/services/secure_channel/device_id_pair.h"
#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
#include "chromeos/services/secure_channel/secure_channel_disconnector.h"
#include "components/cryptauth/secure_channel.h"
namespace device {
class BluetoothAdapter;
} // namespace device
namespace chromeos {
namespace secure_channel {
class BleServiceDataHelper;
class BleSynchronizerBase;
class SecureChannelDisconnector;
class TimerFactory;
// Concrete BleConnectionManager implementation. This class initializes
// BleAdvertiser and BleScanner objects and utilizes them to bootstrap
// connections. Once a connection is found, BleConnectionManagerImpl creates a
// cryptauth::SecureChannel and waits for it to authenticate successfully. Once
// this process is complete, an AuthenticatedChannel is returned to the client.
class BleConnectionManagerImpl : public BleConnectionManager,
public BleAdvertiser::Delegate,
public BleScanner::Delegate,
public cryptauth::SecureChannel::Observer {
public:
class Factory {
public:
static Factory* Get();
static void SetFactoryForTesting(Factory* test_factory);
virtual ~Factory();
virtual std::unique_ptr<BleConnectionManager> BuildInstance(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter,
BleServiceDataHelper* ble_service_data_helper,
TimerFactory* timer_factory);
private:
static Factory* test_factory_;
};
~BleConnectionManagerImpl() override;
private:
BleConnectionManagerImpl(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter,
BleServiceDataHelper* ble_service_data_helper,
TimerFactory* timer_factory);
// BleConnectionManager:
void PerformAttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformUpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformCancelBleInitiatorConnectionAttempt(
const DeviceIdPair& device_id_pair) override;
void PerformAttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformUpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformCancelBleListenerConnectionAttempt(
const DeviceIdPair& device_id_pair) override;
// BleAdvertiser::Delegate:
void OnAdvertisingSlotEnded(
const DeviceIdPair& device_id_pair,
bool replaced_by_higher_priority_advertisement) override;
// BleScanner::Delegate:
void OnReceivedAdvertisement(cryptauth::RemoteDeviceRef remote_device,
device::BluetoothDevice* bluetooth_device,
ConnectionRole connection_role) override;
// cryptauth::SecureChannel::Observer:
void OnSecureChannelStatusChanged(
cryptauth::SecureChannel* secure_channel,
const cryptauth::SecureChannel::Status& old_status,
const cryptauth::SecureChannel::Status& new_status) override;
// Returns whether a channel exists connecting to |remote_device_id|,
// regardless of the local device ID or the role used to create the
// connection.
bool DoesAuthenticatingChannelExist(const std::string& remote_device_id);
// Adds |secure_channel| to |remote_device_id_to_secure_channel_map_| and
// pauses any ongoing attempts to |remote_device_id|, since a connection has
// already been established to that device.
void SetAuthenticatingChannel(
const std::string& remote_device_id,
std::unique_ptr<cryptauth::SecureChannel> secure_channel,
ConnectionRole connection_role);
// Pauses pending connection attempts (scanning and/or advertising) to
// |remote_device_id|.
void PauseConnectionAttemptsToDevice(const std::string& remote_device_id);
// Restarts connections which were paused as part of
// PauseConnectionAttemptsToDevice();
void RestartPausedAttemptsToDevice(const std::string& remote_device_id);
// Checks to see if there is a leftover channel authenticating with
// |remote_device_id| even though there are no pending requests for a
// connection to that device. This situation arises when an active request is
// canceled after a connection has been established but before that connection
// has been fully authenticated. This function disconnects the channel in the
// case that it finds one.
void ProcessPotentialLingeringChannel(const std::string& remote_device_id);
std::string GetRemoteDeviceIdForSecureChannel(
cryptauth::SecureChannel* secure_channel);
void HandleSecureChannelDisconnection(const std::string& remote_device_id,
bool was_authenticating);
void HandleChannelAuthenticated(const std::string& remote_device_id);
// Chooses the connection attempt which will receive the success callback.
// It is possible that there is more than one possible recipient in the case
// that two attempts are made with the same remote device ID and connection
// role but different local device IDs. In the case of multiple possible
// recipients, we arbitrarily choose the one which was registered first.
ConnectionAttemptDetails ChooseChannelRecipient(
const std::string& remote_device_id,
ConnectionRole connection_role);
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
BleServiceDataHelper* ble_service_data_helper_;
std::unique_ptr<BleSynchronizerBase> ble_synchronizer_;
std::unique_ptr<BleAdvertiser> ble_advertiser_;
std::unique_ptr<BleScanner> ble_scanner_;
std::unique_ptr<SecureChannelDisconnector> secure_channel_disconnector_;
using SecureChannelWithRole =
std::pair<std::unique_ptr<cryptauth::SecureChannel>, ConnectionRole>;
base::flat_map<std::string, SecureChannelWithRole>
remote_device_id_to_secure_channel_map_;
base::Optional<std::string> notifying_remote_device_id_;
DISALLOW_COPY_AND_ASSIGN(BleConnectionManagerImpl);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_CONNECTION_MANAGER_IMPL_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/services/secure_channel/ble_connection_manager_impl.h"
#include <memory>
#include <tuple>
#include <utility>
#include "base/bind.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "chromeos/services/secure_channel/authenticated_channel_impl.h"
#include "chromeos/services/secure_channel/ble_advertiser_impl.h"
#include "chromeos/services/secure_channel/ble_constants.h"
#include "chromeos/services/secure_channel/ble_initiator_failure_type.h"
#include "chromeos/services/secure_channel/ble_listener_failure_type.h"
#include "chromeos/services/secure_channel/ble_scanner_impl.h"
#include "chromeos/services/secure_channel/ble_synchronizer.h"
#include "chromeos/services/secure_channel/fake_ble_advertiser.h"
#include "chromeos/services/secure_channel/fake_ble_scanner.h"
#include "chromeos/services/secure_channel/fake_ble_service_data_helper.h"
#include "chromeos/services/secure_channel/fake_ble_synchronizer.h"
#include "chromeos/services/secure_channel/fake_secure_channel_disconnector.h"
#include "chromeos/services/secure_channel/fake_timer_factory.h"
#include "chromeos/services/secure_channel/public/cpp/shared/fake_authenticated_channel.h"
#include "chromeos/services/secure_channel/secure_channel_disconnector_impl.h"
#include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h"
#include "components/cryptauth/fake_connection.h"
#include "components/cryptauth/fake_secure_channel.h"
#include "components/cryptauth/remote_device_test_util.h"
#include "components/cryptauth/secure_channel.h"
#include "device/bluetooth/bluetooth_uuid.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace secure_channel {
namespace {
const size_t kNumTestDevices = 5;
class FakeBleSynchronizerFactory : public BleSynchronizer::Factory {
public:
FakeBleSynchronizerFactory(
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
expected_mock_adapter)
: expected_mock_adapter_(expected_mock_adapter) {}
~FakeBleSynchronizerFactory() override = default;
FakeBleSynchronizer* instance() { return instance_; }
private:
// BleSynchronizer::Factory:
std::unique_ptr<BleSynchronizerBase> BuildInstance(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) override {
EXPECT_EQ(expected_mock_adapter_, bluetooth_adapter);
EXPECT_FALSE(instance_);
auto instance = std::make_unique<FakeBleSynchronizer>();
instance_ = instance.get();
return instance;
}
FakeBleSynchronizer* instance_ = nullptr;
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
expected_mock_adapter_;
DISALLOW_COPY_AND_ASSIGN(FakeBleSynchronizerFactory);
};
class FakeBleAdvertiserFactory : public BleAdvertiserImpl::Factory {
public:
FakeBleAdvertiserFactory(
FakeBleServiceDataHelper* expected_fake_ble_service_data_helper,
FakeBleSynchronizerFactory* fake_ble_synchronizer_factory,
FakeTimerFactory* expected_fake_timer_factory)
: expected_fake_ble_service_data_helper_(
expected_fake_ble_service_data_helper),
fake_ble_synchronizer_factory_(fake_ble_synchronizer_factory),
expected_fake_timer_factory_(expected_fake_timer_factory) {}
~FakeBleAdvertiserFactory() override = default;
FakeBleAdvertiser* instance() { return instance_; }
private:
// BleAdvertiserImpl::Factory:
std::unique_ptr<BleAdvertiser> BuildInstance(
BleAdvertiser::Delegate* delegate,
BleServiceDataHelper* ble_service_data_helper,
BleSynchronizerBase* ble_synchronizer_base,
TimerFactory* timer_factory) override {
EXPECT_EQ(expected_fake_ble_service_data_helper_, ble_service_data_helper);
EXPECT_EQ(fake_ble_synchronizer_factory_->instance(),
ble_synchronizer_base);
EXPECT_EQ(expected_fake_timer_factory_, timer_factory);
EXPECT_FALSE(instance_);
auto instance = std::make_unique<FakeBleAdvertiser>(delegate);
instance_ = instance.get();
return instance;
}
FakeBleAdvertiser* instance_ = nullptr;
FakeBleServiceDataHelper* expected_fake_ble_service_data_helper_;
FakeBleSynchronizerFactory* fake_ble_synchronizer_factory_;
FakeTimerFactory* expected_fake_timer_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeBleAdvertiserFactory);
};
class FakeBleScannerFactory : public BleScannerImpl::Factory {
public:
FakeBleScannerFactory(
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
expected_mock_adapter,
FakeBleServiceDataHelper* expected_fake_ble_service_data_helper,
FakeBleSynchronizerFactory* fake_ble_synchronizer_factory)
: expected_mock_adapter_(expected_mock_adapter),
expected_fake_ble_service_data_helper_(
expected_fake_ble_service_data_helper),
fake_ble_synchronizer_factory_(fake_ble_synchronizer_factory) {}
virtual ~FakeBleScannerFactory() = default;
FakeBleScanner* instance() { return instance_; }
private:
// BleScannerImpl::Factory:
std::unique_ptr<BleScanner> BuildInstance(
BleScanner::Delegate* delegate,
BleServiceDataHelper* service_data_helper,
BleSynchronizerBase* ble_synchronizer_base,
scoped_refptr<device::BluetoothAdapter> adapter) override {
EXPECT_EQ(expected_fake_ble_service_data_helper_, service_data_helper);
EXPECT_EQ(fake_ble_synchronizer_factory_->instance(),
ble_synchronizer_base);
EXPECT_EQ(expected_mock_adapter_, adapter);
EXPECT_FALSE(instance_);
auto instance = std::make_unique<FakeBleScanner>(delegate);
instance_ = instance.get();
return instance;
}
FakeBleScanner* instance_ = nullptr;
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
expected_mock_adapter_;
FakeBleServiceDataHelper* expected_fake_ble_service_data_helper_;
FakeBleSynchronizerFactory* fake_ble_synchronizer_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeBleScannerFactory);
};
class FakeSecureChannelDisconnectorFactory
: public SecureChannelDisconnectorImpl::Factory {
public:
FakeSecureChannelDisconnectorFactory() = default;
~FakeSecureChannelDisconnectorFactory() override = default;
FakeSecureChannelDisconnector* instance() { return instance_; }
private:
// SecureChannelDisconnectorImpl::Factory:
std::unique_ptr<SecureChannelDisconnector> BuildInstance() override {
auto instance = std::make_unique<FakeSecureChannelDisconnector>();
instance_ = instance.get();
return instance;
}
FakeSecureChannelDisconnector* instance_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FakeSecureChannelDisconnectorFactory);
};
class FakeWeaveClientConnectionFactory
: public cryptauth::weave::BluetoothLowEnergyWeaveClientConnection::
Factory {
public:
FakeWeaveClientConnectionFactory(
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
expected_mock_adapter)
: expected_mock_adapter_(expected_mock_adapter) {}
virtual ~FakeWeaveClientConnectionFactory() = default;
void set_expected_bluetooth_device(
device::MockBluetoothDevice* expected_bluetooth_device) {
expected_bluetooth_device_ = expected_bluetooth_device;
}
cryptauth::FakeConnection* last_created_instance() {
return last_created_instance_;
}
private:
// cryptauth::BluetoothLowEnergyWeaveClientConnection::Factory:
std::unique_ptr<cryptauth::Connection> BuildInstance(
cryptauth::RemoteDeviceRef remote_device,
scoped_refptr<device::BluetoothAdapter> adapter,
const device::BluetoothUUID remote_service_uuid,
device::BluetoothDevice* bluetooth_device,
bool should_set_low_connection_latency) override {
EXPECT_EQ(expected_mock_adapter_, adapter);
EXPECT_EQ(device::BluetoothUUID(kGattServerUuid), remote_service_uuid);
EXPECT_FALSE(should_set_low_connection_latency);
auto instance = std::make_unique<cryptauth::FakeConnection>(remote_device);
last_created_instance_ = instance.get();
return instance;
}
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>>
expected_mock_adapter_;
device::MockBluetoothDevice* expected_bluetooth_device_;
cryptauth::FakeConnection* last_created_instance_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FakeWeaveClientConnectionFactory);
};
class FakeSecureChannelFactory : public cryptauth::SecureChannel::Factory {
public:
FakeSecureChannelFactory(
FakeWeaveClientConnectionFactory* fake_weave_client_connection_factory)
: fake_weave_client_connection_factory_(
fake_weave_client_connection_factory) {}
virtual ~FakeSecureChannelFactory() = default;
cryptauth::FakeSecureChannel* last_created_instance() {
return last_created_instance_;
}
private:
// cryptauth::SecureChannel::Factory:
std::unique_ptr<cryptauth::SecureChannel> BuildInstance(
std::unique_ptr<cryptauth::Connection> connection) override {
EXPECT_EQ(fake_weave_client_connection_factory_->last_created_instance(),
connection.get());
auto instance =
std::make_unique<cryptauth::FakeSecureChannel>(std::move(connection));
last_created_instance_ = instance.get();
return instance;
}
FakeWeaveClientConnectionFactory* fake_weave_client_connection_factory_;
cryptauth::FakeSecureChannel* last_created_instance_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FakeSecureChannelFactory);
};
class FakeAuthenticatedChannelFactory
: public AuthenticatedChannelImpl::Factory {
public:
FakeAuthenticatedChannelFactory() = default;
virtual ~FakeAuthenticatedChannelFactory() = default;
void SetExpectationsForNextCall(
cryptauth::FakeSecureChannel* expected_fake_secure_channel,
bool expected_to_be_background_advertisement) {
expected_fake_secure_channel_ = expected_fake_secure_channel;
expected_to_be_background_advertisement_ =
expected_to_be_background_advertisement;
}
FakeAuthenticatedChannel* last_created_instance() {
return last_created_instance_;
}
private:
// AuthenticatedChannelImpl::Factory:
std::unique_ptr<AuthenticatedChannel> BuildInstance(
const std::vector<mojom::ConnectionCreationDetail>&
connection_creation_details,
std::unique_ptr<cryptauth::SecureChannel> secure_channel) override {
EXPECT_EQ(expected_fake_secure_channel_, secure_channel.get());
EXPECT_EQ(1u, connection_creation_details.size());
if (expected_to_be_background_advertisement_) {
EXPECT_EQ(mojom::ConnectionCreationDetail::
REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING,
connection_creation_details[0]);
} else {
EXPECT_EQ(mojom::ConnectionCreationDetail::
REMOTE_DEVICE_USED_FOREGROUND_BLE_ADVERTISING,
connection_creation_details[0]);
}
auto instance = std::make_unique<FakeAuthenticatedChannel>();
last_created_instance_ = instance.get();
return instance;
}
cryptauth::FakeSecureChannel* expected_fake_secure_channel_ = nullptr;
bool expected_to_be_background_advertisement_ = false;
FakeAuthenticatedChannel* last_created_instance_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FakeAuthenticatedChannelFactory);
};
} // namespace
class SecureChannelBleConnectionManagerImplTest : public testing::Test {
protected:
SecureChannelBleConnectionManagerImplTest()
: test_devices_(
cryptauth::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {}
~SecureChannelBleConnectionManagerImplTest() override = default;
// testing::Test:
void SetUp() override {
mock_adapter_ =
base::MakeRefCounted<testing::NiceMock<device::MockBluetoothAdapter>>();
fake_ble_service_data_helper_ =
std::make_unique<FakeBleServiceDataHelper>();
fake_timer_factory_ = std::make_unique<FakeTimerFactory>();
fake_ble_synchronizer_factory_ =
std::make_unique<FakeBleSynchronizerFactory>(mock_adapter_);
BleSynchronizer::Factory::SetFactoryForTesting(
fake_ble_synchronizer_factory_.get());
fake_ble_advertiser_factory_ = std::make_unique<FakeBleAdvertiserFactory>(
fake_ble_service_data_helper_.get(),
fake_ble_synchronizer_factory_.get(), fake_timer_factory_.get());
BleAdvertiserImpl::Factory::SetFactoryForTesting(
fake_ble_advertiser_factory_.get());
fake_ble_scanner_factory_ = std::make_unique<FakeBleScannerFactory>(
mock_adapter_, fake_ble_service_data_helper_.get(),
fake_ble_synchronizer_factory_.get());
BleScannerImpl::Factory::SetFactoryForTesting(
fake_ble_scanner_factory_.get());
fake_secure_channel_disconnector_factory_ =
std::make_unique<FakeSecureChannelDisconnectorFactory>();
SecureChannelDisconnectorImpl::Factory::SetFactoryForTesting(
fake_secure_channel_disconnector_factory_.get());
fake_weave_client_connection_factory_ =
std::make_unique<FakeWeaveClientConnectionFactory>(mock_adapter_);
cryptauth::weave::BluetoothLowEnergyWeaveClientConnection::Factory::
SetInstanceForTesting(fake_weave_client_connection_factory_.get());
fake_secure_channel_factory_ = std::make_unique<FakeSecureChannelFactory>(
fake_weave_client_connection_factory_.get());
cryptauth::SecureChannel::Factory::SetInstanceForTesting(
fake_secure_channel_factory_.get());
fake_authenticated_channel_factory_ =
std::make_unique<FakeAuthenticatedChannelFactory>();
AuthenticatedChannelImpl::Factory::SetFactoryForTesting(
fake_authenticated_channel_factory_.get());
manager_ = BleConnectionManagerImpl::Factory::Get()->BuildInstance(
mock_adapter_, fake_ble_service_data_helper_.get(),
fake_timer_factory_.get());
}
void TearDown() override {
BleSynchronizer::Factory::SetFactoryForTesting(nullptr);
BleAdvertiserImpl::Factory::SetFactoryForTesting(nullptr);
BleScannerImpl::Factory::SetFactoryForTesting(nullptr);
SecureChannelDisconnectorImpl::Factory::SetFactoryForTesting(nullptr);
cryptauth::weave::BluetoothLowEnergyWeaveClientConnection::Factory::
SetInstanceForTesting(nullptr);
cryptauth::SecureChannel::Factory::SetInstanceForTesting(nullptr);
AuthenticatedChannelImpl::Factory::SetFactoryForTesting(nullptr);
}
void AttemptBleInitiatorConnection(const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
bool expected_to_add_request) {
SetInRemoteDeviceIdToMetadataMap(
device_id_pair, ConnectionRole::kInitiatorRole, connection_priority);
EXPECT_FALSE(fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
manager_->AttemptBleInitiatorConnection(
device_id_pair, connection_priority,
base::BindOnce(
&SecureChannelBleConnectionManagerImplTest::OnConnectionSuccess,
base::Unretained(this), device_id_pair,
false /* created_via_background_advertisement */),
base::BindRepeating(
&SecureChannelBleConnectionManagerImplTest::OnBleInitiatorFailure,
base::Unretained(this), device_id_pair));
if (expected_to_add_request) {
EXPECT_EQ(connection_priority,
*fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kInitiatorRole)));
} else {
EXPECT_FALSE(
fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kInitiatorRole)));
}
}
void UpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
bool expected_to_update_priority) {
SetInRemoteDeviceIdToMetadataMap(
device_id_pair, ConnectionRole::kInitiatorRole, connection_priority);
manager_->UpdateBleInitiatorConnectionPriority(device_id_pair,
connection_priority);
if (expected_to_update_priority) {
EXPECT_EQ(connection_priority,
*fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kInitiatorRole)));
} else {
EXPECT_FALSE(
fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kInitiatorRole)));
}
}
void CancelBleInitiatorConnectionAttempt(const DeviceIdPair& device_id_pair) {
RemoveFromRemoteDeviceIdToMetadataMap(device_id_pair,
ConnectionRole::kInitiatorRole);
manager_->CancelBleInitiatorConnectionAttempt(device_id_pair);
EXPECT_FALSE(fake_ble_advertiser()->GetPriorityForRequest(device_id_pair));
EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kInitiatorRole)));
}
void AttemptBleListenerConnection(const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
bool expected_to_add_request) {
SetInRemoteDeviceIdToMetadataMap(
device_id_pair, ConnectionRole::kListenerRole, connection_priority);
manager_->AttemptBleListenerConnection(
device_id_pair, connection_priority,
base::BindOnce(
&SecureChannelBleConnectionManagerImplTest::OnConnectionSuccess,
base::Unretained(this), device_id_pair,
true /* created_via_background_advertisement */),
base::BindRepeating(
&SecureChannelBleConnectionManagerImplTest::OnBleListenerFailure,
base::Unretained(this), device_id_pair));
if (expected_to_add_request) {
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kListenerRole)));
} else {
EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kListenerRole)));
}
}
void UpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
bool expected_to_update_priority) {
SetInRemoteDeviceIdToMetadataMap(
device_id_pair, ConnectionRole::kListenerRole, connection_priority);
manager_->UpdateBleListenerConnectionPriority(device_id_pair,
connection_priority);
if (expected_to_update_priority) {
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kListenerRole)));
} else {
EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
device_id_pair, ConnectionRole::kListenerRole)));
}
}
void CancelBleListenerConnectionAttempt(const DeviceIdPair& device_id_pair) {
RemoveFromRemoteDeviceIdToMetadataMap(device_id_pair,
ConnectionRole::kListenerRole);
manager_->CancelBleListenerConnectionAttempt(device_id_pair);
EXPECT_FALSE(fake_ble_scanner()->HasScanFilter(
BleScanner::ScanFilter(device_id_pair, ConnectionRole::kListenerRole)));
}
void SimulateBleSlotEnding(const DeviceIdPair& device_id_pair,
bool replaced_by_higher_priority_advertisement) {
size_t num_failures_before_call = ble_initiator_failures_.size();
fake_ble_advertiser()->NotifyAdvertisingSlotEnded(
device_id_pair, replaced_by_higher_priority_advertisement);
EXPECT_EQ(num_failures_before_call + 1u, ble_initiator_failures_.size());
EXPECT_EQ(device_id_pair, ble_initiator_failures_.back().first);
EXPECT_EQ(replaced_by_higher_priority_advertisement
? BleInitiatorFailureType::
kInterruptedByHigherPriorityConnectionAttempt
: BleInitiatorFailureType::kTimeoutContactingRemoteDevice,
ble_initiator_failures_.back().second);
}
// Returns the SecureChannel created by this call.
cryptauth::FakeSecureChannel* SimulateConnectionEstablished(
cryptauth::RemoteDeviceRef remote_device,
ConnectionRole connection_role) {
auto mock_bluetooth_device = std::make_unique<device::MockBluetoothDevice>(
mock_adapter_.get(), 0u /* bluetooth_class */, "name", "address",
false /* paired */, false /* connected */);
fake_weave_client_connection_factory_->set_expected_bluetooth_device(
mock_bluetooth_device.get());
fake_ble_scanner()->NotifyReceivedAdvertisementFromDevice(
remote_device, mock_bluetooth_device.get(), connection_role);
// As a result of the connection, all ongoing connection attmepts should
// have been canceled, since a connection is in progress.
EXPECT_TRUE(fake_ble_advertiser()
->GetAllRequestsForRemoteDevice(remote_device.GetDeviceId())
.empty());
EXPECT_TRUE(
fake_ble_scanner()
->GetAllScanFiltersForRemoteDevice(remote_device.GetDeviceId())
.empty());
cryptauth::FakeSecureChannel* last_created_secure_channel =
fake_secure_channel_factory_->last_created_instance();
EXPECT_TRUE(last_created_secure_channel);
return last_created_secure_channel;
}
void SimulateSecureChannelDisconnection(
const std::string& remote_device_id,
bool fail_during_authentication,
cryptauth::FakeSecureChannel* fake_secure_channel) {
size_t num_ble_initiator_failures_before_call =
ble_initiator_failures_.size();
size_t num_ble_listener_failures_before_call =
ble_listener_failures_.size();
// Connect, then disconnect. If needed, start authenticating before
// disconnecting.
fake_secure_channel->ChangeStatus(
cryptauth::SecureChannel::Status::CONNECTED);
if (fail_during_authentication) {
fake_secure_channel->ChangeStatus(
cryptauth::SecureChannel::Status::AUTHENTICATING);
}
fake_secure_channel->ChangeStatus(
cryptauth::SecureChannel::Status::DISCONNECTED);
// Iterate through all pending requests to |remote_device_id|, ensuring that
// all expected failures have been communicated back to the client.
size_t initiator_failures_index = num_ble_initiator_failures_before_call;
size_t listener_failure_index = num_ble_listener_failures_before_call;
for (const auto& tuple :
remote_device_id_to_metadata_map_[remote_device_id]) {
switch (std::get<1>(tuple)) {
case ConnectionRole::kInitiatorRole: {
EXPECT_EQ(std::get<0>(tuple),
ble_initiator_failures_[initiator_failures_index].first);
EXPECT_EQ(fail_during_authentication
? BleInitiatorFailureType::kAuthenticationError
: BleInitiatorFailureType::kGattConnectionError,
ble_initiator_failures_[initiator_failures_index].second);
++initiator_failures_index;
break;
}
case ConnectionRole::kListenerRole: {
if (!fail_during_authentication)
continue;
EXPECT_EQ(std::get<0>(tuple),
ble_listener_failures_[listener_failure_index].first);
EXPECT_EQ(BleListenerFailureType::kAuthenticationError,
ble_listener_failures_[listener_failure_index].second);
++listener_failure_index;
break;
}
}
}
EXPECT_EQ(initiator_failures_index, ble_initiator_failures_.size());
EXPECT_EQ(listener_failure_index, ble_listener_failures_.size());
// All requests which were paused during the connection should have started
// back up again, since the connection became disconnected.
for (const auto& tuple :
remote_device_id_to_metadata_map_[remote_device_id]) {
switch (std::get<1>(tuple)) {
case ConnectionRole::kInitiatorRole: {
EXPECT_EQ(std::get<2>(tuple),
*fake_ble_advertiser()->GetPriorityForRequest(
std::get<0>(tuple)));
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
std::get<0>(tuple), ConnectionRole::kInitiatorRole)));
break;
}
case ConnectionRole::kListenerRole: {
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
std::get<0>(tuple), ConnectionRole::kListenerRole)));
break;
}
}
}
}
void SimulateSecureChannelAuthentication(
const std::string& remote_device_id,
cryptauth::FakeSecureChannel* fake_secure_channel,
bool created_via_background_advertisement) {
fake_authenticated_channel_factory_->SetExpectationsForNextCall(
fake_secure_channel, created_via_background_advertisement);
size_t num_success_callbacks_before_call = successful_connections_.size();
fake_secure_channel->ChangeStatus(
cryptauth::SecureChannel::Status::CONNECTED);
fake_secure_channel->ChangeStatus(
cryptauth::SecureChannel::Status::AUTHENTICATING);
fake_secure_channel->ChangeStatus(
cryptauth::SecureChannel::Status::AUTHENTICATED);
// Verify that the callback was made. Verification that the provided
// DeviceIdPair was correct occurs in OnConnectionSuccess().
EXPECT_EQ(num_success_callbacks_before_call + 1u,
successful_connections_.size());
// For all remaining requests, verify that they were added back.
for (const auto& tuple :
remote_device_id_to_metadata_map_[remote_device_id]) {
switch (std::get<1>(tuple)) {
case ConnectionRole::kInitiatorRole: {
EXPECT_EQ(std::get<2>(tuple),
*fake_ble_advertiser()->GetPriorityForRequest(
std::get<0>(tuple)));
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
std::get<0>(tuple), ConnectionRole::kInitiatorRole)));
break;
}
case ConnectionRole::kListenerRole: {
EXPECT_TRUE(fake_ble_scanner()->HasScanFilter(BleScanner::ScanFilter(
std::get<0>(tuple), ConnectionRole::kListenerRole)));
break;
}
}
}
}
bool WasChannelHandledByDisconnector(
cryptauth::FakeSecureChannel* fake_secure_channel) {
return fake_secure_channel_disconnector()->WasChannelHandled(
fake_secure_channel);
}
const cryptauth::RemoteDeviceRefList& test_devices() { return test_devices_; }
private:
void OnConnectionSuccess(
const DeviceIdPair& device_id_pair,
bool created_via_background_advertisement,
std::unique_ptr<AuthenticatedChannel> authenticated_channel) {
successful_connections_.push_back(
std::make_pair(device_id_pair, std::move(authenticated_channel)));
base::Optional<std::tuple<DeviceIdPair, ConnectionRole, ConnectionPriority>>
tuple_which_received_callback;
for (const auto& tuple :
remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()]) {
if (std::get<1>(tuple) == ConnectionRole::kInitiatorRole &&
!created_via_background_advertisement) {
EXPECT_EQ(std::get<0>(tuple), device_id_pair);
tuple_which_received_callback = tuple;
break;
}
if (std::get<1>(tuple) == ConnectionRole::kListenerRole &&
created_via_background_advertisement) {
EXPECT_EQ(std::get<0>(tuple), device_id_pair);
tuple_which_received_callback = tuple;
break;
}
}
EXPECT_TRUE(tuple_which_received_callback);
// The request which recieved the success callback is automatically removed
// by BleConnectionManager, so it no longer needs to be tracked.
remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()].erase(
*tuple_which_received_callback);
for (const auto& tuple :
remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()]) {
switch (std::get<1>(tuple)) {
case ConnectionRole::kInitiatorRole:
CancelBleInitiatorConnectionAttempt(std::get<0>(tuple));
break;
case ConnectionRole::kListenerRole:
CancelBleListenerConnectionAttempt(std::get<0>(tuple));
break;
}
}
}
void OnBleInitiatorFailure(const DeviceIdPair& device_id_pair,
BleInitiatorFailureType failure_type) {
ble_initiator_failures_.push_back(
std::make_pair(device_id_pair, failure_type));
}
void OnBleListenerFailure(const DeviceIdPair& device_id_pair,
BleListenerFailureType failure_type) {
ble_listener_failures_.push_back(
std::make_pair(device_id_pair, failure_type));
}
void SetInRemoteDeviceIdToMetadataMap(
const DeviceIdPair& device_id_pair,
ConnectionRole connection_role,
ConnectionPriority connection_priority) {
// If the entry already exists, update its priority.
for (auto& tuple :
remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()]) {
if (std::get<0>(tuple) == device_id_pair &&
std::get<1>(tuple) == connection_role) {
std::get<2>(tuple) = connection_priority;
return;
}
}
// Otherwise, add a new entry.
remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()].insert(
std::make_tuple(device_id_pair, connection_role, connection_priority));
}
void RemoveFromRemoteDeviceIdToMetadataMap(const DeviceIdPair& device_id_pair,
ConnectionRole connection_role) {
base::flat_set<std::tuple<DeviceIdPair, ConnectionRole,
ConnectionPriority>>& set_for_remote_device =
remote_device_id_to_metadata_map_[device_id_pair.remote_device_id()];
for (auto it = set_for_remote_device.begin();
it != set_for_remote_device.end(); ++it) {
if (std::get<0>(*it) == device_id_pair &&
std::get<1>(*it) == connection_role) {
set_for_remote_device.erase(it);
return;
}
}
NOTREACHED();
}
FakeBleAdvertiser* fake_ble_advertiser() {
return fake_ble_advertiser_factory_->instance();
}
FakeBleScanner* fake_ble_scanner() {
return fake_ble_scanner_factory_->instance();
}
FakeSecureChannelDisconnector* fake_secure_channel_disconnector() {
return fake_secure_channel_disconnector_factory_->instance();
}
const cryptauth::RemoteDeviceRefList test_devices_;
base::flat_map<
std::string,
base::flat_set<
std::tuple<DeviceIdPair, ConnectionRole, ConnectionPriority>>>
remote_device_id_to_metadata_map_;
std::vector<std::pair<DeviceIdPair, std::unique_ptr<AuthenticatedChannel>>>
successful_connections_;
std::vector<std::pair<DeviceIdPair, BleInitiatorFailureType>>
ble_initiator_failures_;
std::vector<std::pair<DeviceIdPair, BleListenerFailureType>>
ble_listener_failures_;
std::unique_ptr<FakeBleSynchronizerFactory> fake_ble_synchronizer_factory_;
std::unique_ptr<FakeBleAdvertiserFactory> fake_ble_advertiser_factory_;
std::unique_ptr<FakeBleScannerFactory> fake_ble_scanner_factory_;
std::unique_ptr<FakeSecureChannelDisconnectorFactory>
fake_secure_channel_disconnector_factory_;
std::unique_ptr<FakeWeaveClientConnectionFactory>
fake_weave_client_connection_factory_;
std::unique_ptr<FakeSecureChannelFactory> fake_secure_channel_factory_;
std::unique_ptr<FakeAuthenticatedChannelFactory>
fake_authenticated_channel_factory_;
scoped_refptr<testing::NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
std::unique_ptr<FakeBleServiceDataHelper> fake_ble_service_data_helper_;
std::unique_ptr<FakeTimerFactory> fake_timer_factory_;
std::unique_ptr<BleConnectionManager> manager_;
DISALLOW_COPY_AND_ASSIGN(SecureChannelBleConnectionManagerImplTest);
};
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Initiator_UpdatePriority) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kMedium,
true /* expected_to_update_priority */);
UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kHigh,
true /* expected_to_update_priority */);
UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kLow,
true /* expected_to_update_priority */);
UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kMedium,
true /* expected_to_update_priority */);
UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kHigh,
true /* expected_to_update_priority */);
CancelBleInitiatorConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Initiator_AdvertisementsUnansweredThenCanceled) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
UpdateBleInitiatorConnectionPriority(pair, ConnectionPriority::kMedium,
true /* expected_to_update_priority */);
// Fail a few times due to timeouts.
SimulateBleSlotEnding(pair,
false /* replaced_by_higher_priority_advertisement */);
SimulateBleSlotEnding(pair,
false /* replaced_by_higher_priority_advertisement */);
SimulateBleSlotEnding(pair,
false /* replaced_by_higher_priority_advertisement */);
CancelBleInitiatorConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Initiator_FailsAuthenticationThenCanceled) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelDisconnection(pair.remote_device_id(),
true /* fail_during_authentication */,
fake_secure_channel);
CancelBleInitiatorConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Initiator_GattFailureThenCanceled) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelDisconnection(pair.remote_device_id(),
false /* fail_during_authentication */,
fake_secure_channel);
CancelBleInitiatorConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Initiator_SuccessfulConnection) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelAuthentication(
pair.remote_device_id(), fake_secure_channel,
false /* created_via_background_advertisement */);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Listener_UpdatePriority) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kMedium,
true /* expected_to_update_priority */);
UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kHigh,
true /* expected_to_update_priority */);
UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kLow,
true /* expected_to_update_priority */);
UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kMedium,
true /* expected_to_update_priority */);
UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kHigh,
true /* expected_to_update_priority */);
CancelBleListenerConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Listener_FailsAuthenticationThenCanceled) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kListenerRole);
SimulateSecureChannelDisconnection(pair.remote_device_id(),
true /* fail_during_authentication */,
fake_secure_channel);
CancelBleListenerConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Listener_GattFailureThenCanceled) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kListenerRole);
SimulateSecureChannelDisconnection(pair.remote_device_id(),
false /* fail_during_authentication */,
fake_secure_channel);
CancelBleListenerConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
OneRequest_Listener_SuccessfulConnection) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kListenerRole);
SimulateSecureChannelAuthentication(
pair.remote_device_id(), fake_secure_channel,
true /* created_via_background_advertisement */);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_BothInitiator_Failures) {
DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair_1, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleInitiatorConnection(pair_2, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
// One advertisement slot failure each.
SimulateBleSlotEnding(pair_1,
false /* replaced_by_higher_priority_advertisement */);
SimulateBleSlotEnding(pair_2,
false /* replaced_by_higher_priority_advertisement */);
// For pair_1, establish a connection then fail due to GATT errors.
cryptauth::FakeSecureChannel* fake_secure_channel_1 =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelDisconnection(pair_1.remote_device_id(),
false /* fail_during_authentication */,
fake_secure_channel_1);
// For pair_2, establish a connection then fail due to authentication errors.
cryptauth::FakeSecureChannel* fake_secure_channel_2 =
SimulateConnectionEstablished(test_devices()[2],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelDisconnection(pair_2.remote_device_id(),
true /* fail_during_authentication */,
fake_secure_channel_2);
// Cancel both attempts.
CancelBleInitiatorConnectionAttempt(pair_1);
CancelBleInitiatorConnectionAttempt(pair_2);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_BothInitiator_Success) {
DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleInitiatorConnection(pair_1, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleInitiatorConnection(pair_2, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel_1 =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelAuthentication(
pair_1.remote_device_id(), fake_secure_channel_1,
false /* created_via_background_advertisement */);
cryptauth::FakeSecureChannel* fake_secure_channel_2 =
SimulateConnectionEstablished(test_devices()[2],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelAuthentication(
pair_2.remote_device_id(), fake_secure_channel_2,
false /* created_via_background_advertisement */);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_BothListener_Failures) {
DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair_1, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleListenerConnection(pair_2, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel_1 =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kListenerRole);
SimulateSecureChannelDisconnection(pair_1.remote_device_id(),
true /* fail_during_authentication */,
fake_secure_channel_1);
cryptauth::FakeSecureChannel* fake_secure_channel_2 =
SimulateConnectionEstablished(test_devices()[2],
ConnectionRole::kListenerRole);
SimulateSecureChannelDisconnection(pair_2.remote_device_id(),
true /* fail_during_authentication */,
fake_secure_channel_2);
CancelBleListenerConnectionAttempt(pair_1);
CancelBleListenerConnectionAttempt(pair_2);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_BothListener_Success) {
DeviceIdPair pair_1(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
DeviceIdPair pair_2(test_devices()[2].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair_1, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleListenerConnection(pair_2, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel_1 =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kListenerRole);
SimulateSecureChannelAuthentication(
pair_1.remote_device_id(), fake_secure_channel_1,
true /* created_via_background_advertisement */);
cryptauth::FakeSecureChannel* fake_secure_channel_2 =
SimulateConnectionEstablished(test_devices()[2],
ConnectionRole::kListenerRole);
SimulateSecureChannelAuthentication(
pair_2.remote_device_id(), fake_secure_channel_2,
true /* created_via_background_advertisement */);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_SamePairDifferentRole_Failure) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
// GATT failure.
cryptauth::FakeSecureChannel* fake_secure_channel_1 =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelDisconnection(pair.remote_device_id(),
false /* fail_during_authentication */,
fake_secure_channel_1);
// Authentication failure.
cryptauth::FakeSecureChannel* fake_secure_channel_2 =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kListenerRole);
SimulateSecureChannelDisconnection(pair.remote_device_id(),
true /* fail_during_authentication */,
fake_secure_channel_2);
CancelBleListenerConnectionAttempt(pair);
CancelBleInitiatorConnectionAttempt(pair);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_SamePairDifferentRole_Success) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
SimulateSecureChannelAuthentication(
pair.remote_device_id(), fake_secure_channel,
false /* created_via_background_advertisement */);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_SamePairDifferentRole_NewAttemptWhileConnectionInProgress) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
// There is already a connection in progress, so this is not expected to add
// a request to BleAdvertiser/BleScanner.
AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
false /* expected_to_add_request */);
// Update the priority; this also should not cause an update in BleScanner.
UpdateBleListenerConnectionPriority(pair, ConnectionPriority::kMedium,
false /* expected_to_add_request */);
SimulateSecureChannelAuthentication(
pair.remote_device_id(), fake_secure_channel,
false /* created_via_background_advertisement */);
}
TEST_F(SecureChannelBleConnectionManagerImplTest,
TwoRequests_RemoveRequestWhileAuthenticating) {
DeviceIdPair pair(test_devices()[1].GetDeviceId(),
test_devices()[0].GetDeviceId());
AttemptBleListenerConnection(pair, ConnectionPriority::kLow,
true /* expected_to_add_request */);
AttemptBleInitiatorConnection(pair, ConnectionPriority::kMedium,
true /* expected_to_add_request */);
cryptauth::FakeSecureChannel* fake_secure_channel =
SimulateConnectionEstablished(test_devices()[1],
ConnectionRole::kInitiatorRole);
// Before the channel authenticates, remove both ongoing attempts. This should
// cause the ongoing connection to be passed off to the
// SecureChannelDisconnector.
CancelBleListenerConnectionAttempt(pair);
CancelBleInitiatorConnectionAttempt(pair);
EXPECT_TRUE(WasChannelHandledByDisconnector(fake_secure_channel));
}
} // namespace secure_channel
} // namespace chromeos
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/services/secure_channel/fake_ble_connection_manager.h"
namespace chromeos {
namespace secure_channel {
FakeBleConnectionManager::FakeBleConnectionManager() = default;
FakeBleConnectionManager::~FakeBleConnectionManager() = default;
void FakeBleConnectionManager::PerformAttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {}
void FakeBleConnectionManager::PerformUpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {}
void FakeBleConnectionManager::PerformCancelBleInitiatorConnectionAttempt(
const DeviceIdPair& device_id_pair) {}
void FakeBleConnectionManager::PerformAttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {}
void FakeBleConnectionManager::PerformUpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) {}
void FakeBleConnectionManager::PerformCancelBleListenerConnectionAttempt(
const DeviceIdPair& device_id_pair) {}
} // namespace secure_channel
} // namespace chromeos
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_FAKE_BLE_CONNECTION_MANAGER_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_FAKE_BLE_CONNECTION_MANAGER_H_
#include "base/macros.h"
#include "chromeos/services/secure_channel/ble_connection_manager.h"
#include "chromeos/services/secure_channel/connection_role.h"
#include "chromeos/services/secure_channel/device_id_pair.h"
#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
namespace chromeos {
namespace secure_channel {
// Test BleConnectionManager implementation. Each of the overridden functions
// has an empty body.
class FakeBleConnectionManager : public BleConnectionManager {
public:
FakeBleConnectionManager();
~FakeBleConnectionManager() override;
// Make public for testing.
using BleConnectionManager::GetPriorityForAttempt;
using BleConnectionManager::GetDetailsForRemoteDevice;
using BleConnectionManager::DoesAttemptExist;
using BleConnectionManager::NotifyBleInitiatorFailure;
using BleConnectionManager::NotifyBleListenerFailure;
using BleConnectionManager::NotifyConnectionSuccess;
private:
// BleConnectionManager:
void PerformAttemptBleInitiatorConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformUpdateBleInitiatorConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformCancelBleInitiatorConnectionAttempt(
const DeviceIdPair& device_id_pair) override;
void PerformAttemptBleListenerConnection(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformUpdateBleListenerConnectionPriority(
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority) override;
void PerformCancelBleListenerConnectionAttempt(
const DeviceIdPair& device_id_pair) override;
DISALLOW_COPY_AND_ASSIGN(FakeBleConnectionManager);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_FAKE_BLE_CONNECTION_MANAGER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment