Commit d00bd79c authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS MultiDevice] Add PendingBleListenerConnectionRequest.

This class handles connection failures specific to BLE listener.
Because listener roles wait until a connection occurs, this class only
encounters a fatal error when the remote device is invalid.

Bug: 824568, 752273
Change-Id: I2bc162549572aab1b9e9b5e1bfb16cb5e54e8073
Reviewed-on: https://chromium-review.googlesource.com/1072952Reviewed-by: default avatarRyan Hansberry <hansberry@chromium.org>
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561900}
parent c9d21aee
...@@ -29,6 +29,8 @@ static_library("secure_channel") { ...@@ -29,6 +29,8 @@ static_library("secure_channel") {
"multiplexed_channel.h", "multiplexed_channel.h",
"multiplexed_channel_impl.cc", "multiplexed_channel_impl.cc",
"multiplexed_channel_impl.h", "multiplexed_channel_impl.h",
"pending_ble_listener_connection_request.cc",
"pending_ble_listener_connection_request.h",
"pending_connection_request.h", "pending_connection_request.h",
"pending_connection_request_base.h", "pending_connection_request_base.h",
"pending_connection_request_delegate.cc", "pending_connection_request_delegate.cc",
...@@ -94,6 +96,7 @@ source_set("unit_tests") { ...@@ -94,6 +96,7 @@ source_set("unit_tests") {
"connect_to_device_operation_factory_base_unittest.cc", "connect_to_device_operation_factory_base_unittest.cc",
"connection_attempt_base_unittest.cc", "connection_attempt_base_unittest.cc",
"multiplexed_channel_impl_unittest.cc", "multiplexed_channel_impl_unittest.cc",
"pending_ble_listener_connection_request_unittest.cc",
"pending_connection_request_base_unittest.cc", "pending_connection_request_base_unittest.cc",
"single_client_message_proxy_impl_unittest.cc", "single_client_message_proxy_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.
#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_LISTENER_FAILURE_TYPE_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_LISTENER_FAILURE_TYPE_H_
namespace chromeos {
namespace secure_channel {
enum class BleListenerFailureType {
// A connection was formed successfully, but there was an error
// authenticating the connection.
kAuthenticationError,
// BeaconSeeds for the remote device were either unavailable or stale.
kInvalidBeaconSeeds
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_BLE_LISTENER_FAILURE_TYPE_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/pending_ble_listener_connection_request.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
namespace chromeos {
namespace secure_channel {
namespace {
const char kBleListenerReadableRequestTypeForLogging[] = "BLE Listener";
} // namespace
// static
PendingBleListenerConnectionRequest::Factory*
PendingBleListenerConnectionRequest::Factory::test_factory_ = nullptr;
// static
PendingBleListenerConnectionRequest::Factory*
PendingBleListenerConnectionRequest::Factory::Get() {
if (test_factory_)
return test_factory_;
static base::NoDestructor<PendingBleListenerConnectionRequest::Factory>
factory;
return factory.get();
}
// static
void PendingBleListenerConnectionRequest::Factory::SetFactoryForTesting(
Factory* test_factory) {
test_factory_ = test_factory;
}
PendingBleListenerConnectionRequest::Factory::~Factory() = default;
std::unique_ptr<PendingConnectionRequest<BleListenerFailureType>>
PendingBleListenerConnectionRequest::Factory::BuildInstance(
ClientConnectionParameters client_connection_parameters,
PendingConnectionRequestDelegate* delegate) {
return base::WrapUnique(new PendingBleListenerConnectionRequest(
std::move(client_connection_parameters), delegate));
}
PendingBleListenerConnectionRequest::PendingBleListenerConnectionRequest(
ClientConnectionParameters client_connection_parameters,
PendingConnectionRequestDelegate* delegate)
: PendingConnectionRequestBase<BleListenerFailureType>(
std::move(client_connection_parameters),
kBleListenerReadableRequestTypeForLogging,
delegate) {}
PendingBleListenerConnectionRequest::~PendingBleListenerConnectionRequest() =
default;
void PendingBleListenerConnectionRequest::HandleConnectionFailure(
BleListenerFailureType failure_detail) {
switch (failure_detail) {
case BleListenerFailureType::kAuthenticationError:
// Authentication errors cannot be solved via a retry. This situation
// likely means that the keys for this device or the remote device are out
// of sync.
StopRequestDueToConnectionFailures(
mojom::ConnectionAttemptFailureReason::AUTHENTICATION_ERROR);
break;
case BleListenerFailureType::kInvalidBeaconSeeds:
// Valid BeaconSeeds are required for generating BLE scan filters.
StopRequestDueToConnectionFailures(
mojom::ConnectionAttemptFailureReason::
REMOTE_DEVICE_INVALID_BEACON_SEEDS);
break;
}
}
} // 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_PENDING_BLE_LISTENER_CONNECTION_REQUEST_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_PENDING_BLE_LISTENER_CONNECTION_REQUEST_H_
#include "base/macros.h"
#include "chromeos/services/secure_channel/ble_listener_failure_type.h"
#include "chromeos/services/secure_channel/client_connection_parameters.h"
#include "chromeos/services/secure_channel/pending_connection_request_base.h"
namespace chromeos {
namespace secure_channel {
// ConnectionRequest corresponding to BLE connections in the listener role.
class PendingBleListenerConnectionRequest
: public PendingConnectionRequestBase<BleListenerFailureType> {
public:
class Factory {
public:
static Factory* Get();
static void SetFactoryForTesting(Factory* test_factory);
virtual ~Factory();
virtual std::unique_ptr<PendingConnectionRequest<BleListenerFailureType>>
BuildInstance(ClientConnectionParameters client_connection_parameters,
PendingConnectionRequestDelegate* delegate);
private:
static Factory* test_factory_;
};
~PendingBleListenerConnectionRequest() override;
private:
PendingBleListenerConnectionRequest(
ClientConnectionParameters client_connection_parameters,
PendingConnectionRequestDelegate* delegate);
// PendingConnectionRequest<BleListenerFailureType>:
void HandleConnectionFailure(BleListenerFailureType failure_detail) override;
DISALLOW_COPY_AND_ASSIGN(PendingBleListenerConnectionRequest);
};
} // namespace secure_channel
} // namespace chromeos
#endif // CHROMEOS_SERVICES_SECURE_CHANNEL_PENDING_BLE_LISTENER_CONNECTION_REQUEST_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/pending_ble_listener_connection_request.h"
#include <memory>
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "chromeos/services/secure_channel/client_connection_parameters.h"
#include "chromeos/services/secure_channel/fake_pending_connection_request_delegate.h"
#include "chromeos/services/secure_channel/test_client_connection_parameters_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace secure_channel {
namespace {
const char kTestFeature[] = "testFeature";
} // namespace
class SecureChannelPendingBleListenerConnectionRequestTest
: public testing::Test {
protected:
SecureChannelPendingBleListenerConnectionRequestTest() = default;
~SecureChannelPendingBleListenerConnectionRequestTest() override = default;
// testing::Test:
void SetUp() override {
fake_pending_connection_request_delegate_ =
std::make_unique<FakePendingConnectionRequestDelegate>();
auto client_connection_parameters =
TestClientConnectionParametersFactory::Get()->Create(kTestFeature);
client_connection_parameters_ = &client_connection_parameters;
pending_ble_listener_request_ =
PendingBleListenerConnectionRequest::Factory::Get()->BuildInstance(
std::move(client_connection_parameters),
fake_pending_connection_request_delegate_.get());
}
const base::Optional<
PendingConnectionRequestDelegate::FailedConnectionReason>&
GetFailedConnectionReason() {
return fake_pending_connection_request_delegate_
->GetFailedConnectionReasonForId(
pending_ble_listener_request_->GetRequestId());
}
const base::Optional<mojom::ConnectionAttemptFailureReason>&
GetConnectionAttemptFailureReason() {
return fake_connection_delegate()->connection_attempt_failure_reason();
}
void HandleConnectionFailure(BleListenerFailureType failure_type) {
base::RunLoop run_loop;
fake_connection_delegate()->set_closure_for_next_delegate_callback(
run_loop.QuitClosure());
pending_ble_listener_request_->HandleConnectionFailure(failure_type);
run_loop.Run();
}
FakeConnectionDelegate* fake_connection_delegate() {
return TestClientConnectionParametersFactory::Get()
->GetDelegateForParameters(*client_connection_parameters_);
}
private:
const base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<FakePendingConnectionRequestDelegate>
fake_pending_connection_request_delegate_;
ClientConnectionParameters* client_connection_parameters_;
std::unique_ptr<PendingConnectionRequest<BleListenerFailureType>>
pending_ble_listener_request_;
DISALLOW_COPY_AND_ASSIGN(
SecureChannelPendingBleListenerConnectionRequestTest);
};
TEST_F(SecureChannelPendingBleListenerConnectionRequestTest,
HandleAuthenticationError) {
HandleConnectionFailure(BleListenerFailureType::kAuthenticationError);
EXPECT_EQ(
PendingConnectionRequestDelegate::FailedConnectionReason::kRequestFailed,
*GetFailedConnectionReason());
EXPECT_EQ(mojom::ConnectionAttemptFailureReason::AUTHENTICATION_ERROR,
*GetConnectionAttemptFailureReason());
}
TEST_F(SecureChannelPendingBleListenerConnectionRequestTest,
HandleInvalidBeaconSeeds) {
HandleConnectionFailure(BleListenerFailureType::kInvalidBeaconSeeds);
EXPECT_EQ(
PendingConnectionRequestDelegate::FailedConnectionReason::kRequestFailed,
*GetFailedConnectionReason());
EXPECT_EQ(
mojom::ConnectionAttemptFailureReason::REMOTE_DEVICE_INVALID_BEACON_SEEDS,
*GetConnectionAttemptFailureReason());
}
} // 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