Commit 0d13ac29 authored by Ryan Hansberry's avatar Ryan Hansberry Committed by Commit Bot

[CrOS Multidevice] Integrate SecureChannel API into ProximityAuthMonitor.

This injects a ClientChannel into ProximityAuthMonitor, which is used if the
chromeos::features::kMultiDeviceApi is enabled. The ClientChannel is used
to get the current RSSI of the connected remote device.

In the future, the "rolling average RSSI" that is calculated in
ProximityAuthMonitor will be moved to the SecureChannel API, and returned
by it. However, to reduce immediate migration work, that logic is kept
in ProximityAuthMonitor for now.

This CL was originally submitted as [1], but was reverted [2] due to a
subtle bug in a test, which has been fixed at [3]. This CL is unchanged
from the original.

1) https://chromium-review.googlesource.com/c/chromium/src/+/1106616
2) https://chromium-review.googlesource.com/c/chromium/src/+/1111937
3) https://chromium-review.googlesource.com/c/chromium/src/+/1112422

Bug: 824568, 752273
Change-Id: I5fba2dcb73fd4b8da08d93cbfa045b6f6888a93b
Reviewed-on: https://chromium-review.googlesource.com/1112434
Commit-Queue: Ryan Hansberry <hansberry@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569785}
parent b671b76a
...@@ -55,6 +55,8 @@ static_library("proximity_auth") { ...@@ -55,6 +55,8 @@ static_library("proximity_auth") {
"//chromeos", "//chromeos",
"//chromeos/components/proximity_auth/logging", "//chromeos/components/proximity_auth/logging",
"//chromeos/components/proximity_auth/public/interfaces", "//chromeos/components/proximity_auth/public/interfaces",
"//chromeos/services/secure_channel/public/cpp/client",
"//chromeos/services/secure_channel/public/mojom",
"//components/account_id", "//components/account_id",
"//components/cryptauth", "//components/cryptauth",
"//components/cryptauth/ble", "//components/cryptauth/ble",
...@@ -113,6 +115,7 @@ source_set("unit_tests") { ...@@ -113,6 +115,7 @@ source_set("unit_tests") {
"//chromeos", "//chromeos",
"//chromeos/components/proximity_auth/logging", "//chromeos/components/proximity_auth/logging",
"//chromeos/components/proximity_auth/logging:unit_tests", "//chromeos/components/proximity_auth/logging:unit_tests",
"//chromeos/services/secure_channel/public/cpp/client:test_support",
"//components/cryptauth:test_support", "//components/cryptauth:test_support",
"//components/prefs:test_support", "//components/prefs:test_support",
"//components/sync_preferences:test_support", "//components/sync_preferences:test_support",
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "chromeos/components/proximity_auth/metrics.h" #include "chromeos/components/proximity_auth/metrics.h"
#include "chromeos/components/proximity_auth/proximity_auth_pref_manager.h" #include "chromeos/components/proximity_auth/proximity_auth_pref_manager.h"
#include "chromeos/components/proximity_auth/proximity_monitor_observer.h" #include "chromeos/components/proximity_auth/proximity_monitor_observer.h"
#include "chromeos/services/secure_channel/public/cpp/client/client_channel.h"
#include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_adapter_factory.h"
...@@ -33,13 +34,17 @@ const double kRssiSampleWeight = 0.3; ...@@ -33,13 +34,17 @@ const double kRssiSampleWeight = 0.3;
const int kDefaultRssiThreshold = -70; const int kDefaultRssiThreshold = -70;
ProximityMonitorImpl::ProximityMonitorImpl( ProximityMonitorImpl::ProximityMonitorImpl(
cryptauth::RemoteDeviceRef remote_device,
chromeos::secure_channel::ClientChannel* channel,
cryptauth::Connection* connection, cryptauth::Connection* connection,
ProximityAuthPrefManager* pref_manager) ProximityAuthPrefManager* pref_manager)
: connection_(connection), : remote_device_(remote_device),
channel_(channel),
connection_(connection),
pref_manager_(pref_manager),
remote_device_is_in_proximity_(false), remote_device_is_in_proximity_(false),
is_active_(false), is_active_(false),
rssi_threshold_(kDefaultRssiThreshold), rssi_threshold_(kDefaultRssiThreshold),
pref_manager_(pref_manager),
polling_weak_ptr_factory_(this), polling_weak_ptr_factory_(this),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
if (device::BluetoothAdapterFactory::IsBluetoothSupported()) { if (device::BluetoothAdapterFactory::IsBluetoothSupported()) {
...@@ -76,7 +81,7 @@ void ProximityMonitorImpl::RecordProximityMetricsOnAuthSuccess() { ...@@ -76,7 +81,7 @@ void ProximityMonitorImpl::RecordProximityMetricsOnAuthSuccess() {
: metrics::kUnknownProximityValue; : metrics::kUnknownProximityValue;
std::string remote_device_model = metrics::kUnknownDeviceModel; std::string remote_device_model = metrics::kUnknownDeviceModel;
cryptauth::RemoteDeviceRef remote_device = connection_->remote_device(); cryptauth::RemoteDeviceRef remote_device = remote_device_;
if (!remote_device.name().empty()) if (!remote_device.name().empty())
remote_device_model = remote_device.name(); remote_device_model = remote_device.name();
...@@ -131,37 +136,69 @@ bool ProximityMonitorImpl::ShouldPoll() const { ...@@ -131,37 +136,69 @@ bool ProximityMonitorImpl::ShouldPoll() const {
void ProximityMonitorImpl::Poll() { void ProximityMonitorImpl::Poll() {
DCHECK(ShouldPoll()); DCHECK(ShouldPoll());
std::string address = connection_->GetDeviceAddress(); if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); if (channel_->is_disconnected()) {
PA_LOG(ERROR) << "Channel is disconnected.";
ClearProximityState();
return;
}
if (!device) { channel_->GetConnectionMetadata(
PA_LOG(ERROR) << "Unknown Bluetooth device with address " << address; base::BindOnce(&ProximityMonitorImpl::OnGetConnectionMetadata,
ClearProximityState(); weak_ptr_factory_.GetWeakPtr()));
return; } else {
} std::string address = connection_->GetDeviceAddress();
if (!device->IsConnected()) { BluetoothDevice* device = bluetooth_adapter_->GetDevice(address);
PA_LOG(ERROR) << "Bluetooth device with address " << address
<< " is not connected."; if (!device) {
ClearProximityState(); PA_LOG(ERROR) << "Unknown Bluetooth device with address " << address;
return; ClearProximityState();
return;
}
if (!device->IsConnected()) {
PA_LOG(ERROR) << "Bluetooth device with address " << address
<< " is not connected.";
ClearProximityState();
return;
}
device->GetConnectionInfo(
base::BindRepeating(&ProximityMonitorImpl::OnConnectionInfo,
weak_ptr_factory_.GetWeakPtr()));
} }
}
void ProximityMonitorImpl::OnGetConnectionMetadata(
chromeos::secure_channel::mojom::ConnectionMetadataPtr
connection_metadata) {
DCHECK(base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
device->GetConnectionInfo(base::Bind(&ProximityMonitorImpl::OnConnectionInfo, if (connection_metadata->bluetooth_connection_metadata)
weak_ptr_factory_.GetWeakPtr())); OnGetRssi(connection_metadata->bluetooth_connection_metadata->current_rssi);
else
OnGetRssi(base::nullopt);
} }
void ProximityMonitorImpl::OnConnectionInfo( void ProximityMonitorImpl::OnConnectionInfo(
const BluetoothDevice::ConnectionInfo& connection_info) { const BluetoothDevice::ConnectionInfo& connection_info) {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
if (connection_info.rssi == BluetoothDevice::kUnknownPower)
OnGetRssi(base::nullopt);
else
OnGetRssi(connection_info.rssi);
}
void ProximityMonitorImpl::OnGetRssi(const base::Optional<int32_t>& rssi) {
if (!is_active_) { if (!is_active_) {
PA_LOG(INFO) << "[Proximity] Got connection info after stopping"; PA_LOG(INFO) << "Received RSSI after stopping.";
return; return;
} }
if (connection_info.rssi != BluetoothDevice::kUnknownPower) { if (rssi) {
AddSample(connection_info); AddSample(*rssi);
} else { } else {
PA_LOG(WARNING) << "[Proximity] Unknown values received from API: " PA_LOG(WARNING) << "Received invalid RSSI value.";
<< connection_info.rssi;
rssi_rolling_average_.reset(); rssi_rolling_average_.reset();
CheckForProximityStateChange(); CheckForProximityStateChange();
} }
...@@ -177,14 +214,13 @@ void ProximityMonitorImpl::ClearProximityState() { ...@@ -177,14 +214,13 @@ void ProximityMonitorImpl::ClearProximityState() {
rssi_rolling_average_.reset(); rssi_rolling_average_.reset();
} }
void ProximityMonitorImpl::AddSample( void ProximityMonitorImpl::AddSample(int32_t rssi) {
const BluetoothDevice::ConnectionInfo& connection_info) {
double weight = kRssiSampleWeight; double weight = kRssiSampleWeight;
if (!rssi_rolling_average_) { if (!rssi_rolling_average_) {
rssi_rolling_average_.reset(new double(connection_info.rssi)); rssi_rolling_average_.reset(new double(rssi));
} else { } else {
*rssi_rolling_average_ = *rssi_rolling_average_ =
weight * connection_info.rssi + (1 - weight) * (*rssi_rolling_average_); weight * rssi + (1 - weight) * (*rssi_rolling_average_);
} }
CheckForProximityStateChange(); CheckForProximityStateChange();
......
...@@ -11,14 +11,23 @@ ...@@ -11,14 +11,23 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/optional.h"
#include "chromeos/chromeos_features.h"
#include "chromeos/components/proximity_auth/proximity_monitor.h" #include "chromeos/components/proximity_auth/proximity_monitor.h"
#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
#include "components/cryptauth/connection.h" #include "components/cryptauth/connection.h"
#include "components/cryptauth/remote_device_ref.h" #include "components/cryptauth/remote_device_ref.h"
#include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_device.h"
namespace chromeos {
namespace secure_channel {
class ClientChannel;
} // namespace secure_channel
} // namespace chromeos
namespace device { namespace device {
class BluetoothAdapter; class BluetoothAdapter;
} } // namespace device
namespace proximity_auth { namespace proximity_auth {
...@@ -29,7 +38,9 @@ class ProximityMonitorObserver; ...@@ -29,7 +38,9 @@ class ProximityMonitorObserver;
class ProximityMonitorImpl : public ProximityMonitor { class ProximityMonitorImpl : public ProximityMonitor {
public: public:
// The |connection| is not owned, and must outlive |this| instance. // The |connection| is not owned, and must outlive |this| instance.
ProximityMonitorImpl(cryptauth::Connection* connection, ProximityMonitorImpl(cryptauth::RemoteDeviceRef remote_device,
chromeos::secure_channel::ClientChannel* channel,
cryptauth::Connection* connection,
ProximityAuthPrefManager* pref_manager); ProximityAuthPrefManager* pref_manager);
~ProximityMonitorImpl() override; ~ProximityMonitorImpl() override;
...@@ -62,18 +73,19 @@ class ProximityMonitorImpl : public ProximityMonitor { ...@@ -62,18 +73,19 @@ class ProximityMonitorImpl : public ProximityMonitor {
// Polls the connection information. // Polls the connection information.
void Poll(); void Poll();
// Callback to received the polled-for connection info. void OnGetConnectionMetadata(
chromeos::secure_channel::mojom::ConnectionMetadataPtr
connection_metadata);
void OnConnectionInfo( void OnConnectionInfo(
const device::BluetoothDevice::ConnectionInfo& connection_info); const device::BluetoothDevice::ConnectionInfo& connection_info);
void OnGetRssi(const base::Optional<int32_t>& rssi);
// Resets the proximity state to |false|, and clears all member variables // Resets the proximity state to |false|, and clears all member variables
// tracking the proximity state. // tracking the proximity state.
void ClearProximityState(); void ClearProximityState();
// Updates the proximity state with a new |connection_info| sample of the // Updates the proximity state with a new sample of the current RSSI.
// current RSSI. void AddSample(int32_t rssi);
void AddSample(
const device::BluetoothDevice::ConnectionInfo& connection_info);
// Checks whether the proximity state has changed based on the current // Checks whether the proximity state has changed based on the current
// samples. Notifies |observers_| on a change. // samples. Notifies |observers_| on a change.
...@@ -83,10 +95,19 @@ class ProximityMonitorImpl : public ProximityMonitor { ...@@ -83,10 +95,19 @@ class ProximityMonitorImpl : public ProximityMonitor {
// RSSI value. // RSSI value.
void GetRssiThresholdFromPrefs(); void GetRssiThresholdFromPrefs();
// The current connection being monitored. Not owned and must outlive this // Used to get the name of the remote device that ProximitMonitor is
// instance. // communicating with, for metrics purposes.
cryptauth::RemoteDeviceRef remote_device_;
// Used to communicate with the remote device to gauge its proximity via RSSI
// measurement.
chromeos::secure_channel::ClientChannel* channel_;
cryptauth::Connection* connection_; cryptauth::Connection* connection_;
// Used to get determine the user pref for how far away the phone is allowed
// to be.
ProximityAuthPrefManager* pref_manager_;
// The observers attached to the ProximityMonitor. // The observers attached to the ProximityMonitor.
base::ObserverList<ProximityMonitorObserver> observers_; base::ObserverList<ProximityMonitorObserver> observers_;
...@@ -110,10 +131,6 @@ class ProximityMonitorImpl : public ProximityMonitor { ...@@ -110,10 +131,6 @@ class ProximityMonitorImpl : public ProximityMonitor {
// measurement. // measurement.
std::unique_ptr<double> rssi_rolling_average_; std::unique_ptr<double> rssi_rolling_average_;
// Contains perferences that outlive the lifetime of this object and across
// process restarts. Not owned and must outlive this instance.
ProximityAuthPrefManager* pref_manager_;
// Used to vend weak pointers for polling. Using a separate factory for these // Used to vend weak pointers for polling. Using a separate factory for these
// weak pointers allows the weak pointers to be invalidated when polling // weak pointers allows the weak pointers to be invalidated when polling
// stops, which effectively cancels the scheduled tasks. // stops, which effectively cancels the scheduled tasks.
......
...@@ -11,13 +11,16 @@ ...@@ -11,13 +11,16 @@
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h" #include "base/test/simple_test_tick_clock.h"
#include "base/test/test_simple_task_runner.h" #include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chromeos/chromeos_features.h"
#include "chromeos/components/proximity_auth/logging/logging.h" #include "chromeos/components/proximity_auth/logging/logging.h"
#include "chromeos/components/proximity_auth/proximity_auth_profile_pref_manager.h" #include "chromeos/components/proximity_auth/proximity_auth_profile_pref_manager.h"
#include "chromeos/components/proximity_auth/proximity_monitor_observer.h" #include "chromeos/components/proximity_auth/proximity_monitor_observer.h"
#include "chromeos/services/secure_channel/public/cpp/client/fake_client_channel.h"
#include "components/cryptauth/fake_connection.h" #include "components/cryptauth/fake_connection.h"
#include "components/cryptauth/remote_device_ref.h" #include "components/cryptauth/remote_device_ref.h"
#include "components/cryptauth/remote_device_test_util.h" #include "components/cryptauth/remote_device_test_util.h"
...@@ -90,13 +93,18 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test { ...@@ -90,13 +93,18 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test {
"", "",
false /* paired */, false /* paired */,
true /* connected */), true /* connected */),
fake_client_channel_(
std::make_unique<chromeos::secure_channel::FakeClientChannel>()),
remote_device_(cryptauth::RemoteDeviceRefBuilder() remote_device_(cryptauth::RemoteDeviceRefBuilder()
.SetUserId(kRemoteDeviceUserId) .SetUserId(kRemoteDeviceUserId)
.SetName(kRemoteDeviceName) .SetName(kRemoteDeviceName)
.Build()), .Build()),
connection_(remote_device_), connection_(remote_device_),
pref_manager_(new NiceMock<MockProximityAuthPrefManager>()), pref_manager_(new NiceMock<MockProximityAuthPrefManager>()),
monitor_(&connection_, pref_manager_.get()), monitor_(remote_device_,
fake_client_channel_.get(),
&connection_,
pref_manager_.get()),
task_runner_(new base::TestSimpleTaskRunner()), task_runner_(new base::TestSimpleTaskRunner()),
thread_task_runner_handle_(task_runner_) { thread_task_runner_handle_(task_runner_) {
ON_CALL(*bluetooth_adapter_, GetDevice(std::string())) ON_CALL(*bluetooth_adapter_, GetDevice(std::string()))
...@@ -110,16 +118,42 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test { ...@@ -110,16 +118,42 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test {
~ProximityAuthProximityMonitorImplTest() override {} ~ProximityAuthProximityMonitorImplTest() override {}
void SetMultiDeviceApiEnabled() {
scoped_feature_list_.InitAndEnableFeature(
chromeos::features::kMultiDeviceApi);
}
void RunPendingTasks() { task_runner_->RunPendingTasks(); } void RunPendingTasks() { task_runner_->RunPendingTasks(); }
void ProvideConnectionInfo( void ProvideRssi(base::Optional<int32_t> rssi) {
const BluetoothDevice::ConnectionInfo& connection_info) {
RunPendingTasks(); RunPendingTasks();
connection_info_callback_.Run(connection_info);
// Reset the callback to ensure that tests correctly only respond at most if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi)) {
// once per call to GetConnectionInfo(). std::vector<chromeos::secure_channel::mojom::ConnectionCreationDetail>
connection_info_callback_ = BluetoothDevice::ConnectionInfoCallback(); creation_details{
chromeos::secure_channel::mojom::ConnectionCreationDetail::
REMOTE_DEVICE_USED_BACKGROUND_BLE_ADVERTISING};
chromeos::secure_channel::mojom::BluetoothConnectionMetadataPtr
bluetooth_connection_metadata_ptr;
if (rssi) {
bluetooth_connection_metadata_ptr =
chromeos::secure_channel::mojom::BluetoothConnectionMetadata::New(
*rssi);
}
chromeos::secure_channel::mojom::ConnectionMetadataPtr
connection_metadata_ptr =
chromeos::secure_channel::mojom::ConnectionMetadata::New(
creation_details,
std::move(bluetooth_connection_metadata_ptr));
fake_client_channel_->InvokePendingGetConnectionMetadataCallback(
std::move(connection_metadata_ptr));
} else {
ProvideConnectionInfo({rssi ? *rssi : BluetoothDevice::kUnknownPower,
4 /* transmit_power */,
4 /* max_transmit_power */});
}
} }
protected: protected:
...@@ -129,6 +163,8 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test { ...@@ -129,6 +163,8 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test {
// Mocks used for verifying interactions with the Bluetooth subsystem. // Mocks used for verifying interactions with the Bluetooth subsystem.
scoped_refptr<device::MockBluetoothAdapter> bluetooth_adapter_; scoped_refptr<device::MockBluetoothAdapter> bluetooth_adapter_;
NiceMock<device::MockBluetoothDevice> remote_bluetooth_device_; NiceMock<device::MockBluetoothDevice> remote_bluetooth_device_;
std::unique_ptr<chromeos::secure_channel::FakeClientChannel>
fake_client_channel_;
cryptauth::RemoteDeviceRef remote_device_; cryptauth::RemoteDeviceRef remote_device_;
cryptauth::FakeConnection connection_; cryptauth::FakeConnection connection_;
...@@ -139,10 +175,23 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test { ...@@ -139,10 +175,23 @@ class ProximityAuthProximityMonitorImplTest : public testing::Test {
ProximityMonitorImpl monitor_; ProximityMonitorImpl monitor_;
private: private:
void ProvideConnectionInfo(
const BluetoothDevice::ConnectionInfo& connection_info) {
DCHECK(!base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi));
connection_info_callback_.Run(connection_info);
// Reset the callback to ensure that tests correctly only respond at most
// once per call to GetConnectionInfo().
connection_info_callback_ = BluetoothDevice::ConnectionInfoCallback();
}
scoped_refptr<base::TestSimpleTaskRunner> task_runner_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
base::ThreadTaskRunnerHandle thread_task_runner_handle_; base::ThreadTaskRunnerHandle thread_task_runner_handle_;
BluetoothDevice::ConnectionInfoCallback connection_info_callback_; BluetoothDevice::ConnectionInfoCallback connection_info_callback_;
ScopedDisableLoggingForTesting disable_logging_; ScopedDisableLoggingForTesting disable_logging_;
base::test::ScopedFeatureList scoped_feature_list_;
}; };
TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_NeverStarted) { TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_NeverStarted) {
...@@ -150,22 +199,51 @@ TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_NeverStarted) { ...@@ -150,22 +199,51 @@ TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_NeverStarted) {
} }
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_Started_NoConnectionInfoReceivedYet) { IsUnlockAllowed_Started_NoRssiReceivedYet) {
monitor_.Start();
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_Started_NoRssiReceivedYet_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start(); monitor_.Start();
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_RssiInRange) { TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_RssiInRange) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(4);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_RssiInRange_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(4);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
} }
TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_UnknownRssi) { TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_UnknownRssi) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({0, 0, 4}); ProvideRssi(0);
ProvideConnectionInfo({BluetoothDevice::kUnknownPower, 0, 4}); ProvideRssi(base::nullopt);
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_UnknownRssi_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(0);
ProvideRssi(base::nullopt);
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
...@@ -178,20 +256,53 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -178,20 +256,53 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
// Simulate receiving an RSSI reading in proximity. // Simulate receiving an RSSI reading in proximity.
EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1); EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
ProvideConnectionInfo({kRssiThreshold / 2, 4, 4}); ProvideRssi(kRssiThreshold / 2);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate a reading indicating non-proximity. // Simulate a reading indicating non-proximity.
EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1); EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
ProvideConnectionInfo({2 * kRssiThreshold, 4, 4}); ProvideRssi(kRssiThreshold * 2);
ProvideConnectionInfo({2 * kRssiThreshold, 4, 4}); ProvideRssi(kRssiThreshold * 2);
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_InformsObserverOfChanges_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
// Initially, the device is not in proximity.
monitor_.Start();
EXPECT_FALSE(monitor_.IsUnlockAllowed());
// Simulate receiving an RSSI reading in proximity.
EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
ProvideRssi(kRssiThreshold / 2);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate a reading indicating non-proximity.
EXPECT_CALL(observer_, OnProximityStateChanged()).Times(1);
ProvideRssi(kRssiThreshold * 2);
ProvideRssi(kRssiThreshold * 2);
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_StartThenStop) { TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_StartThenStop) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({0, 0, 4}); ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
monitor_.Stop();
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_StartThenStop_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
monitor_.Stop(); monitor_.Stop();
...@@ -201,18 +312,39 @@ TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_StartThenStop) { ...@@ -201,18 +312,39 @@ TEST_F(ProximityAuthProximityMonitorImplTest, IsUnlockAllowed_StartThenStop) {
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_StartThenStopThenStartAgain) { IsUnlockAllowed_StartThenStopThenStartAgain) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({kRssiThreshold / 2, 4, 4}); ProvideRssi(kRssiThreshold / 2);
ProvideConnectionInfo({kRssiThreshold / 2, 4, 4}); ProvideRssi(kRssiThreshold / 2);
ProvideConnectionInfo({kRssiThreshold / 2, 4, 4}); ProvideRssi(kRssiThreshold / 2);
ProvideConnectionInfo({kRssiThreshold / 2, 4, 4}); ProvideRssi(kRssiThreshold / 2);
ProvideConnectionInfo({kRssiThreshold / 2, 4, 4}); ProvideRssi(kRssiThreshold / 2);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
monitor_.Stop(); monitor_.Stop();
// Restarting the monitor should immediately reset the proximity state, rather // Restarting the monitor should immediately reset the proximity state, rather
// than building on the previous rolling average. // than building on the previous rolling average.
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({kRssiThreshold - 1, 4, 4}); ProvideRssi(kRssiThreshold - 1);
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_StartThenStopThenStartAgain_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(kRssiThreshold / 2);
ProvideRssi(kRssiThreshold / 2);
ProvideRssi(kRssiThreshold / 2);
ProvideRssi(kRssiThreshold / 2);
ProvideRssi(kRssiThreshold / 2);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
monitor_.Stop();
// Restarting the monitor should immediately reset the proximity state, rather
// than building on the previous rolling average.
monitor_.Start();
ProvideRssi(kRssiThreshold - 1);
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
...@@ -220,15 +352,33 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -220,15 +352,33 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_RemoteDeviceRemainsInProximity) { IsUnlockAllowed_RemoteDeviceRemainsInProximity) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({kRssiThreshold / 2 + 1, 4, 4}); ProvideRssi(kRssiThreshold / 2 + 1);
ProvideConnectionInfo({kRssiThreshold / 2 - 1, 4, 4}); ProvideRssi(kRssiThreshold / 2 - 1);
ProvideConnectionInfo({kRssiThreshold / 2 + 2, 4, 4}); ProvideRssi(kRssiThreshold / 2 + 2);
ProvideConnectionInfo({kRssiThreshold / 2 - 3, 4, 4}); ProvideRssi(kRssiThreshold / 2 - 3);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Brief drops in RSSI should be handled by weighted averaging.
ProvideRssi(kRssiThreshold - 5);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_RemoteDeviceRemainsInProximity_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(kRssiThreshold / 2 + 1);
ProvideRssi(kRssiThreshold / 2 - 1);
ProvideRssi(kRssiThreshold / 2 + 2);
ProvideRssi(kRssiThreshold / 2 - 3);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Brief drops in RSSI should be handled by weighted averaging. // Brief drops in RSSI should be handled by weighted averaging.
ProvideConnectionInfo({kRssiThreshold - 5, 4, 4}); ProvideRssi(kRssiThreshold - 5);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
} }
...@@ -238,22 +388,49 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -238,22 +388,49 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
monitor_.Start(); monitor_.Start();
// Start with a device in proximity. // Start with a device in proximity.
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate readings for the remote device leaving proximity.
ProvideRssi(-1);
ProvideRssi(-4);
ProvideRssi(0);
ProvideRssi(-10);
ProvideRssi(-15);
ProvideRssi(-20);
ProvideRssi(kRssiThreshold);
ProvideRssi(kRssiThreshold - 10);
ProvideRssi(kRssiThreshold - 20);
ProvideRssi(kRssiThreshold - 20);
ProvideRssi(kRssiThreshold - 20);
ProvideRssi(kRssiThreshold - 20);
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_RemoteDeviceLeavesProximity_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
// Start with a device in proximity.
ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate readings for the remote device leaving proximity. // Simulate readings for the remote device leaving proximity.
ProvideConnectionInfo({-1, 4, 4}); ProvideRssi(-1);
ProvideConnectionInfo({-4, 4, 4}); ProvideRssi(-4);
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
ProvideConnectionInfo({-10, 4, 4}); ProvideRssi(-10);
ProvideConnectionInfo({-15, 4, 4}); ProvideRssi(-15);
ProvideConnectionInfo({-20, 4, 4}); ProvideRssi(-20);
ProvideConnectionInfo({kRssiThreshold, 4, 4}); ProvideRssi(kRssiThreshold);
ProvideConnectionInfo({kRssiThreshold - 10, 4, 4}); ProvideRssi(kRssiThreshold - 10);
ProvideConnectionInfo({kRssiThreshold - 20, 4, 4}); ProvideRssi(kRssiThreshold - 20);
ProvideConnectionInfo({kRssiThreshold - 20, 4, 4}); ProvideRssi(kRssiThreshold - 20);
ProvideConnectionInfo({kRssiThreshold - 20, 4, 4}); ProvideRssi(kRssiThreshold - 20);
ProvideConnectionInfo({kRssiThreshold - 20, 4, 4}); ProvideRssi(kRssiThreshold - 20);
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
...@@ -263,19 +440,41 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -263,19 +440,41 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
monitor_.Start(); monitor_.Start();
// Start with a device out of proximity. // Start with a device out of proximity.
ProvideConnectionInfo({2 * kRssiThreshold, 4, 4}); ProvideRssi(kRssiThreshold * 2);
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
// Simulate readings for the remote device entering proximity. // Simulate readings for the remote device entering proximity.
ProvideConnectionInfo({-15, 4, 4}); ProvideRssi(-15);
ProvideConnectionInfo({-8, 4, 4}); ProvideRssi(-8);
ProvideConnectionInfo({-12, 4, 4}); ProvideRssi(-12);
ProvideConnectionInfo({-18, 4, 4}); ProvideRssi(-18);
ProvideConnectionInfo({-7, 4, 4}); ProvideRssi(-7);
ProvideConnectionInfo({-3, 4, 4}); ProvideRssi(-3);
ProvideConnectionInfo({-2, 4, 4}); ProvideRssi(-2);
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_RemoteDeviceEntersProximity_MultiDeviceApiEnabled) {
monitor_.Start();
// Start with a device out of proximity.
ProvideRssi(kRssiThreshold * 2);
EXPECT_FALSE(monitor_.IsUnlockAllowed());
// Simulate readings for the remote device entering proximity.
ProvideRssi(-15);
ProvideRssi(-8);
ProvideRssi(-12);
ProvideRssi(-18);
ProvideRssi(-7);
ProvideRssi(-3);
ProvideRssi(-2);
ProvideRssi(0);
ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
} }
...@@ -285,7 +484,24 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -285,7 +484,24 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
monitor_.Start(); monitor_.Start();
// Start with the device known to the adapter and in proximity. // Start with the device known to the adapter and in proximity.
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate it being forgotten.
ON_CALL(*bluetooth_adapter_, GetDevice(std::string()))
.WillByDefault(Return(nullptr));
EXPECT_CALL(observer_, OnProximityStateChanged());
RunPendingTasks();
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_DeviceNotKnownToAdapter_MultiDeviceApiEnabled) {
monitor_.Start();
// Start with the device known to the adapter and in proximity.
ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate it being forgotten. // Simulate it being forgotten.
...@@ -302,7 +518,7 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -302,7 +518,7 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
monitor_.Start(); monitor_.Start();
// Start with the device connected and in proximity. // Start with the device connected and in proximity.
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed()); EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate it disconnecting. // Simulate it disconnecting.
...@@ -313,20 +529,67 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -313,20 +529,67 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_DeviceNotConnected_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
// Start with the device connected and in proximity.
ProvideRssi(0);
EXPECT_TRUE(monitor_.IsUnlockAllowed());
// Simulate it disconnecting.
fake_client_channel_->NotifyDisconnected();
EXPECT_CALL(observer_, OnProximityStateChanged());
RunPendingTasks();
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_ConnectionInfoReceivedAfterStopping) { IsUnlockAllowed_ConnectionInfoReceivedAfterStopping) {
monitor_.Start(); monitor_.Start();
monitor_.Stop(); monitor_.Stop();
ProvideConnectionInfo({0, 4, 4}); ProvideRssi(0);
EXPECT_FALSE(monitor_.IsUnlockAllowed());
}
TEST_F(
ProximityAuthProximityMonitorImplTest,
IsUnlockAllowed_ConnectionInfoReceivedAfterStopping_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
monitor_.Stop();
ProvideRssi(0);
EXPECT_FALSE(monitor_.IsUnlockAllowed()); EXPECT_FALSE(monitor_.IsUnlockAllowed());
} }
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
RecordProximityMetricsOnAuthSuccess_NormalValues) { RecordProximityMetricsOnAuthSuccess_NormalValues) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({0, 0, 4}); ProvideRssi(0);
ProvideRssi(-20);
base::HistogramTester histogram_tester;
monitor_.RecordProximityMetricsOnAuthSuccess();
histogram_tester.ExpectUniqueSample("EasyUnlock.AuthProximity.RollingRssi",
-6, 1);
histogram_tester.ExpectUniqueSample(
"EasyUnlock.AuthProximity.RemoteDeviceModelHash",
1881443083 /* hash of "LGE Nexus 5" */, 1);
}
TEST_F(ProximityAuthProximityMonitorImplTest,
RecordProximityMetricsOnAuthSuccess_NormalValues_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(0);
ProvideConnectionInfo({-20, 3, 4}); ProvideRssi(-20);
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
monitor_.RecordProximityMetricsOnAuthSuccess(); monitor_.RecordProximityMetricsOnAuthSuccess();
...@@ -340,7 +603,21 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -340,7 +603,21 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
RecordProximityMetricsOnAuthSuccess_ClampedValues) { RecordProximityMetricsOnAuthSuccess_ClampedValues) {
monitor_.Start(); monitor_.Start();
ProvideConnectionInfo({-99999, 99999, 12345}); ProvideRssi(-99999);
base::HistogramTester histogram_tester;
monitor_.RecordProximityMetricsOnAuthSuccess();
histogram_tester.ExpectUniqueSample("EasyUnlock.AuthProximity.RollingRssi",
-100, 1);
}
TEST_F(
ProximityAuthProximityMonitorImplTest,
RecordProximityMetricsOnAuthSuccess_ClampedValues_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
monitor_.Start();
ProvideRssi(-99999);
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
monitor_.RecordProximityMetricsOnAuthSuccess(); monitor_.RecordProximityMetricsOnAuthSuccess();
...@@ -351,15 +628,44 @@ TEST_F(ProximityAuthProximityMonitorImplTest, ...@@ -351,15 +628,44 @@ TEST_F(ProximityAuthProximityMonitorImplTest,
TEST_F(ProximityAuthProximityMonitorImplTest, TEST_F(ProximityAuthProximityMonitorImplTest,
RecordProximityMetricsOnAuthSuccess_UnknownValues) { RecordProximityMetricsOnAuthSuccess_UnknownValues) {
// Note: A device without a recorded name will have "Unknown" as its name. // Note: A device without a recorded name will have "Unknown" as its name.
cryptauth::FakeConnection connection(cryptauth::RemoteDeviceRefBuilder() cryptauth::RemoteDeviceRef remote_device = cryptauth::RemoteDeviceRefBuilder()
.SetUserId(kRemoteDeviceUserId) .SetUserId(kRemoteDeviceUserId)
.SetName(std::string()) .SetName(std::string())
.Build()); .Build();
cryptauth::FakeConnection connection(remote_device);
ProximityMonitorImpl monitor(remote_device, fake_client_channel_.get(),
&connection, pref_manager_.get());
monitor.AddObserver(&observer_);
monitor.Start();
ProvideRssi(127);
ProximityMonitorImpl monitor(&connection, pref_manager_.get()); base::HistogramTester histogram_tester;
monitor.RecordProximityMetricsOnAuthSuccess();
histogram_tester.ExpectUniqueSample("EasyUnlock.AuthProximity.RollingRssi",
127, 1);
histogram_tester.ExpectUniqueSample(
"EasyUnlock.AuthProximity.RemoteDeviceModelHash",
-1808066424 /* hash of "Unknown" */, 1);
}
TEST_F(
ProximityAuthProximityMonitorImplTest,
RecordProximityMetricsOnAuthSuccess_UnknownValues_MultiDeviceApiEnabled) {
SetMultiDeviceApiEnabled();
// Note: A device without a recorded name will have "Unknown" as its name.
cryptauth::RemoteDeviceRef remote_device = cryptauth::RemoteDeviceRefBuilder()
.SetUserId(kRemoteDeviceUserId)
.SetName(std::string())
.Build();
cryptauth::FakeConnection connection(remote_device);
ProximityMonitorImpl monitor(remote_device, fake_client_channel_.get(),
&connection, pref_manager_.get());
monitor.AddObserver(&observer_); monitor.AddObserver(&observer_);
monitor.Start(); monitor.Start();
ProvideConnectionInfo({127, 127, 127}); ProvideRssi(127);
base::HistogramTester histogram_tester; base::HistogramTester histogram_tester;
monitor.RecordProximityMetricsOnAuthSuccess(); monitor.RecordProximityMetricsOnAuthSuccess();
......
...@@ -324,7 +324,10 @@ void UnlockManagerImpl::OnAuthAttempted(mojom::AuthType auth_type) { ...@@ -324,7 +324,10 @@ void UnlockManagerImpl::OnAuthAttempted(mojom::AuthType auth_type) {
std::unique_ptr<ProximityMonitor> UnlockManagerImpl::CreateProximityMonitor( std::unique_ptr<ProximityMonitor> UnlockManagerImpl::CreateProximityMonitor(
cryptauth::Connection* connection, cryptauth::Connection* connection,
ProximityAuthPrefManager* pref_manager) { ProximityAuthPrefManager* pref_manager) {
return std::make_unique<ProximityMonitorImpl>(connection, pref_manager); // TODO(crbug.com/752273): Inject a real ClientChannel.
return std::make_unique<ProximityMonitorImpl>(connection->remote_device(),
nullptr /* channel */,
connection, pref_manager);
} }
void UnlockManagerImpl::SendSignInChallenge() { void UnlockManagerImpl::SendSignInChallenge() {
......
...@@ -14,9 +14,16 @@ FakeClientChannel::FakeClientChannel() = default; ...@@ -14,9 +14,16 @@ FakeClientChannel::FakeClientChannel() = default;
FakeClientChannel::~FakeClientChannel() = default; FakeClientChannel::~FakeClientChannel() = default;
void FakeClientChannel::InvokePendingGetConnectionMetadataCallback(
mojom::ConnectionMetadataPtr connection_metadata) {
std::move(get_connection_metadata_callback_queue_.front())
.Run(std::move(connection_metadata));
get_connection_metadata_callback_queue_.pop();
}
void FakeClientChannel::PerformGetConnectionMetadata( void FakeClientChannel::PerformGetConnectionMetadata(
base::OnceCallback<void(mojom::ConnectionMetadataPtr)> callback) { base::OnceCallback<void(mojom::ConnectionMetadataPtr)> callback) {
std::move(callback).Run(std::move(connection_metadata_for_next_call_)); get_connection_metadata_callback_queue_.push(std::move(callback));
} }
void FakeClientChannel::PerformSendMessage(const std::string& payload, void FakeClientChannel::PerformSendMessage(const std::string& payload,
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_CLIENT_CHANNEL_H_ #ifndef CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_CLIENT_CHANNEL_H_
#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_CLIENT_CHANNEL_H_ #define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_CLIENT_FAKE_CLIENT_CHANNEL_H_
#include <queue>
#include "base/macros.h" #include "base/macros.h"
#include "chromeos/services/secure_channel/public/cpp/client/client_channel.h" #include "chromeos/services/secure_channel/public/cpp/client/client_channel.h"
#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h" #include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
...@@ -22,11 +24,8 @@ class FakeClientChannel : public ClientChannel { ...@@ -22,11 +24,8 @@ class FakeClientChannel : public ClientChannel {
using ClientChannel::NotifyDisconnected; using ClientChannel::NotifyDisconnected;
using ClientChannel::NotifyMessageReceived; using ClientChannel::NotifyMessageReceived;
void set_connection_metadata_for_next_call( void InvokePendingGetConnectionMetadataCallback(
mojom::ConnectionMetadataPtr connection_metadata_for_next_call) { mojom::ConnectionMetadataPtr connection_metadata);
connection_metadata_for_next_call_ =
std::move(connection_metadata_for_next_call);
}
std::vector<std::pair<std::string, base::OnceClosure>>& sent_messages() { std::vector<std::pair<std::string, base::OnceClosure>>& sent_messages() {
return sent_messages_; return sent_messages_;
...@@ -41,7 +40,10 @@ class FakeClientChannel : public ClientChannel { ...@@ -41,7 +40,10 @@ class FakeClientChannel : public ClientChannel {
void PerformSendMessage(const std::string& payload, void PerformSendMessage(const std::string& payload,
base::OnceClosure on_sent_callback) override; base::OnceClosure on_sent_callback) override;
mojom::ConnectionMetadataPtr connection_metadata_for_next_call_; // Queues up callbacks passed into PerformGetConnectionMetadata(), to be
// invoked later.
std::queue<base::OnceCallback<void(mojom::ConnectionMetadataPtr)>>
get_connection_metadata_callback_queue_;
std::vector<std::pair<std::string, base::OnceClosure>> sent_messages_; std::vector<std::pair<std::string, base::OnceClosure>> sent_messages_;
DISALLOW_COPY_AND_ASSIGN(FakeClientChannel); DISALLOW_COPY_AND_ASSIGN(FakeClientChannel);
......
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