Commit 977a408a authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS PhoneHub] Add NearbyInitiatorOperation

This is the ConnectToDeviceOperation implementation for a Nearby
Connections attempt in the initiator role. A follow-up CL creates
instances of this class when performing a connection attempt.

Bug: 1106937
Change-Id: Ie47af35bb23d1d751de1c5833b3acdfb0768824c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2415534
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#808099}
parent 99cd9b9d
...@@ -110,6 +110,8 @@ static_library("secure_channel") { ...@@ -110,6 +110,8 @@ static_library("secure_channel") {
"nearby_connection_manager_impl.h", "nearby_connection_manager_impl.h",
"nearby_initiator_failure_type.cc", "nearby_initiator_failure_type.cc",
"nearby_initiator_failure_type.h", "nearby_initiator_failure_type.h",
"nearby_initiator_operation.cc",
"nearby_initiator_operation.h",
"pending_ble_connection_request_base.h", "pending_ble_connection_request_base.h",
"pending_ble_initiator_connection_request.cc", "pending_ble_initiator_connection_request.cc",
"pending_ble_initiator_connection_request.h", "pending_ble_initiator_connection_request.h",
...@@ -294,6 +296,7 @@ source_set("unit_tests") { ...@@ -294,6 +296,7 @@ source_set("unit_tests") {
"foreground_eid_generator_unittest.cc", "foreground_eid_generator_unittest.cc",
"multiplexed_channel_impl_unittest.cc", "multiplexed_channel_impl_unittest.cc",
"nearby_connection_manager_impl_unittest.cc", "nearby_connection_manager_impl_unittest.cc",
"nearby_initiator_operation_unittest.cc",
"pending_ble_connection_request_base_unittest.cc", "pending_ble_connection_request_base_unittest.cc",
"pending_ble_initiator_connection_request_unittest.cc", "pending_ble_initiator_connection_request_unittest.cc",
"pending_ble_listener_connection_request_unittest.cc", "pending_ble_listener_connection_request_unittest.cc",
......
// Copyright 2020 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/nearby_initiator_operation.h"
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "chromeos/services/secure_channel/authenticated_channel.h"
#include "chromeos/services/secure_channel/nearby_connection_manager.h"
namespace chromeos {
namespace secure_channel {
// static
NearbyInitiatorOperation::Factory*
NearbyInitiatorOperation::Factory::test_factory_ = nullptr;
// static
std::unique_ptr<ConnectToDeviceOperation<NearbyInitiatorFailureType>>
NearbyInitiatorOperation::Factory::Create(
NearbyConnectionManager* nearby_connection_manager,
ConnectToDeviceOperation<
NearbyInitiatorFailureType>::ConnectionSuccessCallback success_callback,
const ConnectToDeviceOperation<
NearbyInitiatorFailureType>::ConnectionFailedCallback& failure_callback,
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
scoped_refptr<base::TaskRunner> task_runner) {
if (test_factory_) {
return test_factory_->CreateInstance(
nearby_connection_manager, std::move(success_callback),
std::move(failure_callback), device_id_pair, connection_priority,
std::move(task_runner));
}
return base::WrapUnique(new NearbyInitiatorOperation(
nearby_connection_manager, std::move(success_callback),
std::move(failure_callback), device_id_pair, connection_priority,
std::move(task_runner)));
}
// static
void NearbyInitiatorOperation::Factory::SetFactoryForTesting(
Factory* test_factory) {
test_factory_ = test_factory;
}
NearbyInitiatorOperation::Factory::~Factory() = default;
NearbyInitiatorOperation::NearbyInitiatorOperation(
NearbyConnectionManager* nearby_connection_manager,
ConnectToDeviceOperation<
NearbyInitiatorFailureType>::ConnectionSuccessCallback success_callback,
const ConnectToDeviceOperation<
NearbyInitiatorFailureType>::ConnectionFailedCallback& failure_callback,
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
scoped_refptr<base::TaskRunner> task_runner)
: ConnectToDeviceOperationBase<NearbyInitiatorFailureType>(
std::move(success_callback),
std::move(failure_callback),
device_id_pair,
connection_priority,
task_runner),
nearby_connection_manager_(nearby_connection_manager) {}
NearbyInitiatorOperation::~NearbyInitiatorOperation() = default;
void NearbyInitiatorOperation::PerformAttemptConnectionToDevice(
ConnectionPriority connection_priority) {
nearby_connection_manager_->AttemptNearbyInitiatorConnection(
device_id_pair(),
base::BindOnce(&NearbyInitiatorOperation::OnSuccessfulConnection,
weak_ptr_factory_.GetWeakPtr()),
base::BindRepeating(&NearbyInitiatorOperation::OnConnectionFailure,
weak_ptr_factory_.GetWeakPtr()));
}
void NearbyInitiatorOperation::PerformCancellation() {
nearby_connection_manager_->CancelNearbyInitiatorConnectionAttempt(
device_id_pair());
}
void NearbyInitiatorOperation::PerformUpdateConnectionPriority(
ConnectionPriority connection_priority) {
// Note: Nearby Connections are not performed differently based on the
// connection priority, so this function is intentionally empty.
}
void NearbyInitiatorOperation::OnSuccessfulConnection(
std::unique_ptr<AuthenticatedChannel> authenticated_channel) {
OnSuccessfulConnectionAttempt(std::move(authenticated_channel));
}
void NearbyInitiatorOperation::OnConnectionFailure(
NearbyInitiatorFailureType failure_type) {
OnFailedConnectionAttempt(failure_type);
}
} // namespace secure_channel
} // namespace chromeos
// Copyright 2020 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_NEARBY_INITIATOR_OPERATION_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_NEARBY_INITIATOR_OPERATION_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromeos/services/secure_channel/connect_to_device_operation.h"
#include "chromeos/services/secure_channel/connect_to_device_operation_base.h"
#include "chromeos/services/secure_channel/nearby_initiator_failure_type.h"
#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
namespace chromeos {
namespace secure_channel {
class NearbyConnectionManager;
// Attempts to connect to a remote device over Nearby Connections via the
// initiator role.
class NearbyInitiatorOperation
: public ConnectToDeviceOperationBase<NearbyInitiatorFailureType> {
public:
class Factory {
public:
static std::unique_ptr<ConnectToDeviceOperation<NearbyInitiatorFailureType>>
Create(NearbyConnectionManager* nearby_connection_manager,
ConnectToDeviceOperation<NearbyInitiatorFailureType>::
ConnectionSuccessCallback success_callback,
const ConnectToDeviceOperation<NearbyInitiatorFailureType>::
ConnectionFailedCallback& failure_callback,
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
scoped_refptr<base::TaskRunner> task_runner =
base::ThreadTaskRunnerHandle::Get());
static void SetFactoryForTesting(Factory* test_factory);
protected:
virtual ~Factory();
virtual std::unique_ptr<
ConnectToDeviceOperation<NearbyInitiatorFailureType>>
CreateInstance(NearbyConnectionManager* nearby_connection_manager,
ConnectToDeviceOperation<NearbyInitiatorFailureType>::
ConnectionSuccessCallback success_callback,
const ConnectToDeviceOperation<NearbyInitiatorFailureType>::
ConnectionFailedCallback& failure_callback,
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
scoped_refptr<base::TaskRunner> task_runner) = 0;
private:
static Factory* test_factory_;
};
NearbyInitiatorOperation(const NearbyInitiatorOperation&) = delete;
NearbyInitiatorOperation& operator=(const NearbyInitiatorOperation&) = delete;
~NearbyInitiatorOperation() override;
private:
NearbyInitiatorOperation(
NearbyConnectionManager* nearby_connection_manager,
ConnectToDeviceOperation<NearbyInitiatorFailureType>::
ConnectionSuccessCallback success_callback,
const ConnectToDeviceOperation<NearbyInitiatorFailureType>::
ConnectionFailedCallback& failure_callback,
const DeviceIdPair& device_id_pair,
ConnectionPriority connection_priority,
scoped_refptr<base::TaskRunner> task_runner);
// ConnectToDeviceOperationBase<NearbyInitiatorFailureType>:
void PerformAttemptConnectionToDevice(
ConnectionPriority connection_priority) override;
void PerformCancellation() override;
void PerformUpdateConnectionPriority(
ConnectionPriority connection_priority) override;
void OnSuccessfulConnection(
std::unique_ptr<AuthenticatedChannel> authenticated_channel);
void OnConnectionFailure(NearbyInitiatorFailureType failure_type);
NearbyConnectionManager* nearby_connection_manager_;
base::WeakPtrFactory<NearbyInitiatorOperation> weak_ptr_factory_{this};
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_NEARBY_INITIATOR_OPERATION_H_
\ No newline at end of file
// Copyright 2020 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/nearby_initiator_operation.h"
#include <memory>
#include "base/bind.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "chromeos/services/secure_channel/device_id_pair.h"
#include "chromeos/services/secure_channel/fake_authenticated_channel.h"
#include "chromeos/services/secure_channel/fake_nearby_connection_manager.h"
#include "chromeos/services/secure_channel/nearby_initiator_failure_type.h"
#include "chromeos/services/secure_channel/public/cpp/shared/connection_priority.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace secure_channel {
const char kTestRemoteDeviceId[] = "testRemoteDeviceId";
const char kTestLocalDeviceId[] = "testLocalDeviceId";
constexpr const ConnectionPriority kTestConnectionPriority =
ConnectionPriority::kLow;
class SecureChannelNearbyInitiatorOperationTest : public testing::Test {
protected:
SecureChannelNearbyInitiatorOperationTest()
: device_id_pair_(kTestRemoteDeviceId, kTestLocalDeviceId) {}
SecureChannelNearbyInitiatorOperationTest(
const SecureChannelNearbyInitiatorOperationTest&) = delete;
SecureChannelNearbyInitiatorOperationTest& operator=(
const SecureChannelNearbyInitiatorOperationTest&) = delete;
~SecureChannelNearbyInitiatorOperationTest() override = default;
// testing::Test:
void SetUp() override {
fake_nearby_connection_manager_ =
std::make_unique<FakeNearbyConnectionManager>();
auto test_task_runner = base::MakeRefCounted<base::TestSimpleTaskRunner>();
operation_ = NearbyInitiatorOperation::Factory::Create(
fake_nearby_connection_manager_.get(),
base::BindOnce(&SecureChannelNearbyInitiatorOperationTest::
OnSuccessfulConnectionAttempt,
base::Unretained(this)),
base::BindRepeating(&SecureChannelNearbyInitiatorOperationTest::
OnFailedConnectionAttempt,
base::Unretained(this)),
device_id_pair_, kTestConnectionPriority, test_task_runner);
test_task_runner->RunUntilIdle();
}
const DeviceIdPair& device_id_pair() { return device_id_pair_; }
void FailAttempt(NearbyInitiatorFailureType failure_type) {
fake_nearby_connection_manager_->NotifyNearbyInitiatorFailure(
device_id_pair_, failure_type);
EXPECT_EQ(failure_type, failure_type_from_callback_);
}
FakeNearbyConnectionManager* fake_nearby_connection_manager() {
return fake_nearby_connection_manager_.get();
}
AuthenticatedChannel* channel_from_callback() {
return channel_from_callback_.get();
}
ConnectToDeviceOperation<NearbyInitiatorFailureType>* operation() {
return operation_.get();
}
private:
void OnSuccessfulConnectionAttempt(
std::unique_ptr<AuthenticatedChannel> authenticated_channel) {
EXPECT_FALSE(channel_from_callback_);
channel_from_callback_ = std::move(authenticated_channel);
}
void OnFailedConnectionAttempt(NearbyInitiatorFailureType failure_type) {
failure_type_from_callback_ = failure_type;
}
const base::test::TaskEnvironment task_environment_;
std::unique_ptr<FakeNearbyConnectionManager> fake_nearby_connection_manager_;
DeviceIdPair device_id_pair_;
std::unique_ptr<AuthenticatedChannel> channel_from_callback_;
base::Optional<NearbyInitiatorFailureType> failure_type_from_callback_;
std::unique_ptr<ConnectToDeviceOperation<NearbyInitiatorFailureType>>
operation_;
};
TEST_F(SecureChannelNearbyInitiatorOperationTest, Succeed) {
auto fake_authenticated_channel =
std::make_unique<FakeAuthenticatedChannel>();
FakeAuthenticatedChannel* fake_authenticated_channel_raw =
fake_authenticated_channel.get();
fake_nearby_connection_manager()->NotifyNearbyInitiatorConnectionSuccess(
device_id_pair(), std::move(fake_authenticated_channel));
EXPECT_EQ(fake_authenticated_channel_raw, channel_from_callback());
// The operation should no longer be present in NearbyConnectionManager.
EXPECT_FALSE(
fake_nearby_connection_manager()->DoesAttemptExist(device_id_pair()));
}
TEST_F(SecureChannelNearbyInitiatorOperationTest, Fail) {
static const NearbyInitiatorFailureType all_types[] = {
NearbyInitiatorFailureType::kTimeoutDiscoveringDevice,
NearbyInitiatorFailureType::kNearbyApiError,
NearbyInitiatorFailureType::kConnectionRejected,
NearbyInitiatorFailureType::kConnectivityError,
NearbyInitiatorFailureType::kAuthenticationError};
for (const auto& failure_type : all_types) {
FailAttempt(failure_type);
}
operation()->Cancel();
EXPECT_FALSE(
fake_nearby_connection_manager()->DoesAttemptExist(device_id_pair()));
}
} // namespace secure_channel
} // namespace chromeos
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