receive mode is now enabled when fast init advert is received. added testing for sharing qt backend.

This commit is contained in:
Lasan Mahaliyana
2026-07-31 22:40:07 +05:30
parent 1dda9b431d
commit 205aacefca
6 changed files with 604 additions and 7 deletions
+2
View File
@@ -0,0 +1,2 @@
CompileFlags:
Add: ["-Ibazel-out/k8-fastbuild/bin", "-DNO_WEBRTC"]
+1 -1
View File
@@ -59,7 +59,7 @@ bazel-*
/.clwb/
/dist/
/sharing/linux/dist-minimal/
/sharing/linux/app/linuxdeploy.AppImage
/sharing/linux/app/linuxdeploy*
# Devcontainers
# /.devcontainer/
+27
View File
@@ -58,6 +58,7 @@ qt_cc_library(
"//sharing:transfer_metadata",
"//sharing:types",
"//sharing/flags/generated:generated_flags",
"//sharing/internal/api:platform",
"//sharing/linux:linux_sharing_platform",
"//sharing/proto:enums_cc_proto",
"@com_google_absl//absl/time",
@@ -68,6 +69,32 @@ qt_cc_library(
],
)
cc_test(
name = "backend_test",
size = "small",
srcs = ["backend_test.cc"],
deps = [
":backend",
"//sharing:attachments",
"//sharing:transfer_metadata",
"//sharing/internal/api:platform",
"@com_google_googletest//:gtest_main",
"@rules_qt//:qt_core",
"@rules_qt//:qt_gui",
"@rules_qt//:qt_hdrs",
"@rules_qt//:qt_labs_platform",
"@rules_qt//:qt_opengl",
"@rules_qt//:qt_qml",
"@rules_qt//:qt_qml_meta",
"@rules_qt//:qt_qml_workerscript",
"@rules_qt//:qt_quick",
"@rules_qt//:qt_quick_controls2",
"@rules_qt//:qt_quick_layouts",
"@rules_qt//:qt_quick_shapes",
"@rules_qt//:qt_widgets",
],
)
cc_library(
name = "native_file_logging",
srcs = ["native_file_logging.cc"],
+223 -4
View File
@@ -30,6 +30,7 @@ namespace {
using NearbySharingService = nearby::sharing::NearbySharingService;
constexpr std::chrono::seconds kShutdownTimeout(10);
constexpr int kReceiveTimeoutMilliseconds = 30 * 1000;
QString ToQString(const std::string& value) {
return QString::fromStdString(value);
@@ -359,11 +360,19 @@ Backend::Backend(QObject* parent)
: QObject(parent),
targets_(this),
transfers_(this),
platform_(
std::make_unique<nearby::sharing::linux::LinuxSharingPlatform>()),
fast_init_manager_(&platform_->GetFastInitiationManager()),
send_transfer_callback_(*this, false),
receive_transfer_callback_(*this, true) {
receive_timeout_timer_.setSingleShot(true);
receive_timeout_timer_.setInterval(kReceiveTimeoutMilliseconds);
connect(&receive_timeout_timer_, &QTimer::timeout, this,
&Backend::OnReceiveTimeout);
ConfigureFlags();
service_ = nearby::sharing::NearbySharingServiceFactory::GetInstance()
->CreateSharingService(platform_, &analytics_recorder_,
->CreateSharingService(*platform_, &analytics_recorder_,
/*event_logger=*/nullptr,
/*supports_file_sync=*/false);
if (service_ == nullptr) {
@@ -389,7 +398,7 @@ Backend::Backend(QObject* parent)
status == NearbySharingService::StatusCodes::kOk;
backend->ReportStatus(QStringLiteral("Initialize"), status);
if (backend->initialized_) {
backend->DriveMode();
backend->StartFastInitiationMonitoring();
} else {
backend->desired_mode_ = Mode::kNone;
}
@@ -397,6 +406,24 @@ Backend::Backend(QObject* parent)
});
}
Backend::Backend(NearbySharingService& service,
nearby::api::FastInitiationManager& fast_init_manager,
int receive_timeout_milliseconds, QObject* parent)
: QObject(parent),
targets_(this),
transfers_(this),
fast_init_manager_(&fast_init_manager),
service_(&service),
send_transfer_callback_(*this, false),
receive_transfer_callback_(*this, true),
initialized_(true) {
receive_timeout_timer_.setSingleShot(true);
receive_timeout_timer_.setInterval(receive_timeout_milliseconds);
connect(&receive_timeout_timer_, &QTimer::timeout, this,
&Backend::OnReceiveTimeout);
StartFastInitiationMonitoring();
}
Backend::~Backend() {
shutdown();
}
@@ -406,11 +433,22 @@ QString Backend::hostname() const {
}
void Backend::startReceive() {
SetDesiredMode(Mode::kReceive);
if (service_ == nullptr || shutting_down_) {
return;
}
StartFastInitiationMonitoring();
}
void Backend::startDiscovery() {
SetDesiredMode(Mode::kDiscovery);
if (service_ == nullptr || shutting_down_) {
return;
}
monitoring_requested_ = false;
receive_timeout_timer_.stop();
receive_window_pending_ = false;
receive_offer_received_ = false;
fallback_receive_window_ = false;
StopFastInitiationScanningForDiscovery();
}
bool Backend::sendFile(qint64 share_target_id, const QString& path) {
@@ -477,6 +515,12 @@ void Backend::shutdown() {
return;
}
shutting_down_ = true;
monitoring_requested_ = false;
receive_timeout_timer_.stop();
auto& fast_init_manager = *fast_init_manager_;
if (fast_init_manager.IsScanning()) {
fast_init_manager.StopScanning(nullptr);
}
desired_mode_ = Mode::kNone;
const auto status = ShutdownService(*service_);
if (status != NearbySharingService::StatusCodes::kOk) {
@@ -526,6 +570,8 @@ void Backend::OnTransferUpdate(
if (receive_mode &&
transfer.status() ==
TransferMetadata::Status::kAwaitingLocalConfirmation) {
backend->receive_offer_received_ = true;
backend->receive_timeout_timer_.stop();
emit backend->incomingTransfer(target.id);
}
});
@@ -628,6 +674,7 @@ void Backend::OnModeStopped(Mode mode,
ReportStatus(QStringLiteral("Stop sharing mode"), status);
}
DriveMode();
MaybeStartFastInitiationScanning();
}
void Backend::OnModeStarted(Mode mode,
@@ -638,11 +685,183 @@ void Backend::OnModeStarted(Mode mode,
}
if (status == NearbySharingService::StatusCodes::kOk) {
active_mode_ = mode;
if (mode == Mode::kReceive && receive_window_pending_) {
receive_window_pending_ = false;
receive_offer_received_ = false;
receive_timeout_timer_.start();
}
} else {
desired_mode_ = Mode::kNone;
receive_window_pending_ = false;
receive_timeout_timer_.stop();
if (fallback_receive_window_) {
monitoring_requested_ = false;
}
ReportStatus(QStringLiteral("Start sharing mode"), status);
}
DriveMode();
MaybeStartFastInitiationScanning();
}
void Backend::StartFastInitiationMonitoring() {
monitoring_requested_ = true;
fallback_receive_used_ = false;
fallback_receive_window_ = false;
receive_window_pending_ = false;
receive_offer_received_ = false;
receive_timeout_timer_.stop();
SetDesiredMode(Mode::kNone);
MaybeStartFastInitiationScanning();
}
void Backend::MaybeStartFastInitiationScanning() {
if (!initialized_ || service_ == nullptr || shutting_down_ ||
!monitoring_requested_ || fast_init_scan_stop_in_flight_ ||
mode_operation_in_flight_ || active_mode_ != Mode::kNone ||
desired_mode_ != Mode::kNone) {
return;
}
if (fallback_receive_window_ && fallback_receive_used_) {
OpenReceiveWindow(/*fallback=*/true);
return;
}
auto& fast_init_manager = *fast_init_manager_;
if (fast_init_manager.IsScanning()) {
return;
}
sender_present_ = false;
receive_trigger_armed_ = true;
QPointer<Backend> backend(this);
fast_init_manager.StartScanning(
[backend]() {
if (backend) {
PostStatus(backend, [backend]() {
if (backend) {
backend->OnFastInitiationDevicesDiscovered();
}
});
}
},
[backend]() {
if (backend) {
PostStatus(backend, [backend]() {
if (backend) {
backend->OnFastInitiationDevicesNotDiscovered();
}
});
}
},
[backend](nearby::api::FastInitiationManager::Error error) {
if (backend) {
PostStatus(backend, [backend, error]() {
if (backend) {
backend->OnFastInitiationScanningError(error);
}
});
}
});
}
void Backend::StopFastInitiationScanningForDiscovery() {
auto& fast_init_manager = *fast_init_manager_;
if (!fast_init_manager.IsScanning()) {
SetDesiredMode(Mode::kDiscovery);
return;
}
if (fast_init_scan_stop_in_flight_) {
return;
}
fast_init_scan_stop_in_flight_ = true;
QPointer<Backend> backend(this);
fast_init_manager.StopScanning([backend]() {
if (backend) {
PostStatus(backend, [backend]() {
if (backend) {
backend->OnFastInitiationScanningStoppedForDiscovery();
}
});
}
});
}
void Backend::OnFastInitiationScanningStoppedForDiscovery() {
fast_init_scan_stop_in_flight_ = false;
sender_present_ = false;
receive_trigger_armed_ = true;
if (!shutting_down_ && !monitoring_requested_) {
SetDesiredMode(Mode::kDiscovery);
} else {
MaybeStartFastInitiationScanning();
}
}
void Backend::OnFastInitiationDevicesDiscovered() {
if (shutting_down_ || !monitoring_requested_) {
return;
}
sender_present_ = true;
const bool should_open_receive = receive_trigger_armed_;
receive_trigger_armed_ = false;
if (!should_open_receive || active_mode_ != Mode::kNone ||
desired_mode_ != Mode::kNone || mode_operation_in_flight_) {
return;
}
OpenReceiveWindow(/*fallback=*/false);
}
void Backend::OnFastInitiationDevicesNotDiscovered() {
if (shutting_down_ || !monitoring_requested_) {
return;
}
sender_present_ = false;
receive_trigger_armed_ = true;
}
void Backend::OnFastInitiationScanningError(
nearby::api::FastInitiationManager::Error error) {
if (shutting_down_ || !monitoring_requested_) {
return;
}
qWarning() << "Fast Initiation scanning failed with error"
<< static_cast<int>(error);
if (fallback_receive_used_) {
monitoring_requested_ = false;
return;
}
fallback_receive_used_ = true;
fallback_receive_window_ = true;
if (active_mode_ == Mode::kReceive || desired_mode_ == Mode::kReceive) {
return;
}
if (active_mode_ == Mode::kNone && desired_mode_ == Mode::kNone &&
!mode_operation_in_flight_) {
OpenReceiveWindow(/*fallback=*/true);
}
}
void Backend::OpenReceiveWindow(bool fallback) {
fallback_receive_window_ = fallback;
receive_window_pending_ = true;
receive_offer_received_ = false;
SetDesiredMode(Mode::kReceive);
}
void Backend::OnReceiveTimeout() {
if (shutting_down_ || receive_offer_received_ ||
active_mode_ != Mode::kReceive) {
return;
}
if (fallback_receive_window_) {
monitoring_requested_ = false;
}
receive_window_pending_ = false;
fallback_receive_window_ = false;
SetDesiredMode(Mode::kNone);
}
std::function<void(NearbySharingService::StatusCodes)> Backend::StatusCallback(
+29 -2
View File
@@ -10,6 +10,7 @@
#include <QAbstractListModel>
#include <QObject>
#include <QString>
#include <QTimer>
#include "QtQmlIntegration/qqmlintegration.h"
#include "qtmetamacros.h"
@@ -131,6 +132,8 @@ class Backend : public QObject,
void outgoingTransferStartFailed(qint64 share_target_id);
private:
friend class BackendTestPeer;
using NearbySharingService = nearby::sharing::NearbySharingService;
using ShareTarget = nearby::sharing::ShareTarget;
using TransferMetadata = nearby::sharing::TransferMetadata;
@@ -157,6 +160,10 @@ class Backend : public QObject,
kDiscovery,
};
Backend(NearbySharingService& service,
nearby::api::FastInitiationManager& fast_init_manager,
int receive_timeout_milliseconds, QObject* parent);
void OnShareTargetDiscovered(const ShareTarget& target) override;
void OnShareTargetUpdated(const ShareTarget& target) override;
void OnShareTargetLost(const ShareTarget& target) override;
@@ -168,6 +175,16 @@ class Backend : public QObject,
void DriveMode();
void OnModeStopped(Mode mode, NearbySharingService::StatusCodes status);
void OnModeStarted(Mode mode, NearbySharingService::StatusCodes status);
void StartFastInitiationMonitoring();
void MaybeStartFastInitiationScanning();
void StopFastInitiationScanningForDiscovery();
void OnFastInitiationScanningStoppedForDiscovery();
void OnFastInitiationDevicesDiscovered();
void OnFastInitiationDevicesNotDiscovered();
void OnFastInitiationScanningError(
nearby::api::FastInitiationManager::Error error);
void OpenReceiveWindow(bool fallback);
void OnReceiveTimeout();
std::function<void(NearbySharingService::StatusCodes)> StatusCallback(
QString operation);
void ReportStatus(const QString& operation,
@@ -176,13 +193,23 @@ class Backend : public QObject,
ShareTargetModel targets_;
ShareTransferModel transfers_;
nearby::sharing::linux::NoOpAnalyticsRecorder analytics_recorder_;
nearby::sharing::linux::LinuxSharingPlatform platform_;
std::unique_ptr<nearby::sharing::linux::LinuxSharingPlatform> platform_;
nearby::api::FastInitiationManager* fast_init_manager_ = nullptr;
NearbySharingService* service_ = nullptr;
TransferCallback send_transfer_callback_;
TransferCallback receive_transfer_callback_;
QTimer receive_timeout_timer_;
Mode active_mode_ = Mode::kNone;
Mode desired_mode_ = Mode::kReceive;
Mode desired_mode_ = Mode::kNone;
bool initialized_ = false;
bool mode_operation_in_flight_ = false;
bool monitoring_requested_ = true;
bool fast_init_scan_stop_in_flight_ = false;
bool sender_present_ = false;
bool receive_trigger_armed_ = true;
bool receive_window_pending_ = false;
bool receive_offer_received_ = false;
bool fallback_receive_window_ = false;
bool fallback_receive_used_ = false;
bool shutting_down_ = false;
};
+322
View File
@@ -0,0 +1,322 @@
#include "sharing/linux/app/backend.h"
#include <cstdlib>
#include <memory>
#include <QCoreApplication>
#include <QEventLoop>
#include "gtest/gtest.h"
#include "sharing/attachment_container.h"
#include "sharing/transfer_metadata_builder.h"
class BackendTestPeer {
public:
static std::unique_ptr<Backend> Create(
nearby::sharing::NearbySharingService& service,
nearby::api::FastInitiationManager& fast_init_manager) {
return std::unique_ptr<Backend>(
new Backend(service, fast_init_manager,
/*receive_timeout_milliseconds=*/5000, nullptr));
}
static bool IsIdle(const Backend& backend) {
return backend.active_mode_ == Backend::Mode::kNone;
}
static bool IsReceiving(const Backend& backend) {
return backend.active_mode_ == Backend::Mode::kReceive;
}
static bool IsDiscovering(const Backend& backend) {
return backend.active_mode_ == Backend::Mode::kDiscovery;
}
static bool IsReceiveTimerActive(const Backend& backend) {
return backend.receive_timeout_timer_.isActive();
}
static bool IsMonitoringRequested(const Backend& backend) {
return backend.monitoring_requested_;
}
static void ExpireReceiveWindow(Backend& backend) {
backend.OnReceiveTimeout();
}
};
namespace {
class TestSharingService final : public nearby::sharing::NearbySharingService {
public:
void AddObserver(Observer*) override {}
void RemoveObserver(Observer*) override {}
void Shutdown(std::function<void(StatusCodes)> callback) override {
callback(StatusCodes::kOk);
}
void RegisterSendSurface(
nearby::sharing::TransferUpdateCallback*,
nearby::sharing::ShareTargetDiscoveredCallback*, SendSurfaceState,
nearby::sharing::Advertisement::BlockedVendorId, bool,
absl::AnyInvocable<void(StatusCodes)> callback) override {
send_registered_ = true;
std::move(callback)(StatusCodes::kOk);
}
void UnregisterSendSurface(
nearby::sharing::TransferUpdateCallback*,
absl::AnyInvocable<void(StatusCodes)> callback) override {
send_registered_ = false;
std::move(callback)(StatusCodes::kOk);
}
void RegisterReceiveSurface(
nearby::sharing::TransferUpdateCallback* callback, ReceiveSurfaceState,
nearby::sharing::Advertisement::BlockedVendorId,
absl::AnyInvocable<void(StatusCodes)> status_callback) override {
receive_callback_ = callback;
std::move(status_callback)(StatusCodes::kOk);
}
void UnregisterReceiveSurface(
nearby::sharing::TransferUpdateCallback*,
absl::AnyInvocable<void(StatusCodes)> callback) override {
receive_callback_ = nullptr;
std::move(callback)(StatusCodes::kOk);
}
void ClearForegroundReceiveSurfaces(
absl::AnyInvocable<void(StatusCodes)> callback) override {
receive_callback_ = nullptr;
std::move(callback)(StatusCodes::kOk);
}
bool IsTransferring() const override { return false; }
bool IsScanning() const override { return send_registered_; }
bool IsBluetoothPresent() const override { return true; }
bool IsBluetoothPowered() const override { return true; }
bool IsExtendedAdvertisingSupported() const override { return true; }
bool IsLanConnected() const override { return true; }
std::string GetQrCodeUrl() const override { return {}; }
void SendAttachments(int64_t,
std::unique_ptr<nearby::sharing::AttachmentContainer>,
std::function<void(StatusCodes)> callback) override {
callback(StatusCodes::kOk);
}
void Accept(int64_t, std::function<void(StatusCodes)> callback) override {
callback(StatusCodes::kOk);
}
void Reject(int64_t, std::function<void(StatusCodes)> callback) override {
callback(StatusCodes::kOk);
}
void Cancel(int64_t, std::function<void(StatusCodes)> callback) override {
callback(StatusCodes::kOk);
}
void InitiatePairing(
int64_t, nearby::sharing::service::proto::BindingRequest::Type,
absl::AnyInvocable<void(StatusCodes) &&> callback) override {
std::move(callback)(StatusCodes::kOk);
}
void SetVisibility(
nearby::sharing::proto::DeviceVisibility, absl::Duration,
absl::AnyInvocable<void(StatusCodes) &&> callback) override {
std::move(callback)(StatusCodes::kOk);
}
std::string Dump() const override { return {}; }
void UpdateFilePathsInProgress(bool) override {}
nearby::sharing::NearbyShareSettings* GetSettings() override {
return nullptr;
}
nearby::sharing::NearbyShareCertificateManager* GetCertificateManager()
override {
return nullptr;
}
nearby::sharing::AccountManager* GetAccountManager() override {
return nullptr;
}
nearby::Clock& GetClock() override { std::abort(); }
void SetAlternateServiceUuidForDiscovery(uint16_t) override {}
nearby::sharing::SyncManager& sync_manager() override { std::abort(); }
nearby::sharing::OutgoingTargetsManager& outgoing_targets_manager() override {
std::abort();
}
void UpdateBackupSavePath(
absl::string_view, absl::string_view,
absl::AnyInvocable<void(StatusCodes)> callback) override {
std::move(callback)(StatusCodes::kOk);
}
void FireReceiveTransferUpdate(
const nearby::sharing::ShareTarget& target,
const nearby::sharing::AttachmentContainer& attachments,
const nearby::sharing::TransferMetadata& metadata) {
ASSERT_NE(receive_callback_, nullptr);
receive_callback_->OnTransferUpdate(target, attachments, metadata);
}
private:
bool send_registered_ = false;
nearby::sharing::TransferUpdateCallback* receive_callback_ = nullptr;
};
class TestFastInitiationManager final
: public nearby::api::FastInitiationManager {
public:
void StartAdvertising(nearby::api::FastInitBleBeacon::FastInitType,
std::function<void()> callback,
std::function<void(Error)>) override {
if (callback) callback();
}
void StopAdvertising(std::function<void()> callback) override {
if (callback) callback();
}
void StartScanning(std::function<void()> discovered_callback,
std::function<void()> not_discovered_callback,
std::function<void(Error)> error_callback) override {
discovered_callback_ = std::move(discovered_callback);
not_discovered_callback_ = std::move(not_discovered_callback);
error_callback_ = std::move(error_callback);
is_scanning_ = true;
}
void StopScanning(std::function<void()> callback) override {
stopped_callback_ = std::move(callback);
is_scanning_ = false;
}
bool IsAdvertising() override { return false; }
bool IsScanning() override { return is_scanning_; }
void FireDiscovered() { discovered_callback_(); }
void FireNotDiscovered() { not_discovered_callback_(); }
void FireError(Error error) { error_callback_(error); }
void CompleteStop() {
if (stopped_callback_) std::move(stopped_callback_)();
}
private:
bool is_scanning_ = false;
std::function<void()> discovered_callback_;
std::function<void()> not_discovered_callback_;
std::function<void()> stopped_callback_;
std::function<void(Error)> error_callback_;
};
QCoreApplication& TestApplication() {
static int argc = 1;
static char application_name[] = "backend_test";
static char* argv[] = {application_name, nullptr};
static QCoreApplication application(argc, argv);
return application;
}
void DrainEvents() {
static_cast<void>(TestApplication());
for (int i = 0; i < 4; ++i) {
QCoreApplication::processEvents(QEventLoop::AllEvents);
}
}
class BackendFastInitiationTest : public testing::Test {
protected:
void SetUp() override {
static_cast<void>(TestApplication());
backend_ = BackendTestPeer::Create(service_, fast_init_manager_);
}
void TearDown() override {
backend_.reset();
DrainEvents();
}
TestSharingService service_;
TestFastInitiationManager fast_init_manager_;
std::unique_ptr<Backend> backend_;
};
TEST_F(BackendFastInitiationTest, StartupScansWithoutReceiving) {
EXPECT_TRUE(fast_init_manager_.IsScanning());
EXPECT_TRUE(BackendTestPeer::IsIdle(*backend_));
EXPECT_FALSE(BackendTestPeer::IsReceiveTimerActive(*backend_));
}
TEST_F(BackendFastInitiationTest, PresenceOpensTimedReceiveWindow) {
fast_init_manager_.FireDiscovered();
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsReceiving(*backend_));
EXPECT_TRUE(BackendTestPeer::IsReceiveTimerActive(*backend_));
EXPECT_TRUE(fast_init_manager_.IsScanning());
}
TEST_F(BackendFastInitiationTest,
TimeoutRequiresSenderAbsenceBeforeAnotherWindow) {
fast_init_manager_.FireDiscovered();
DrainEvents();
BackendTestPeer::ExpireReceiveWindow(*backend_);
DrainEvents();
ASSERT_TRUE(BackendTestPeer::IsIdle(*backend_));
fast_init_manager_.FireDiscovered();
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsIdle(*backend_));
fast_init_manager_.FireNotDiscovered();
fast_init_manager_.FireDiscovered();
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsReceiving(*backend_));
}
TEST_F(BackendFastInitiationTest, SenderLossDoesNotCloseCurrentWindow) {
fast_init_manager_.FireDiscovered();
DrainEvents();
fast_init_manager_.FireNotDiscovered();
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsReceiving(*backend_));
EXPECT_TRUE(BackendTestPeer::IsReceiveTimerActive(*backend_));
}
TEST_F(BackendFastInitiationTest, IncomingOfferCancelsReceiveTimeout) {
fast_init_manager_.FireDiscovered();
DrainEvents();
nearby::sharing::ShareTarget target;
target.id = 1;
auto attachments = nearby::sharing::AttachmentContainer::Builder().Build();
service_.FireReceiveTransferUpdate(
target, *attachments,
nearby::sharing::TransferMetadataBuilder()
.set_status(nearby::sharing::TransferMetadata::Status::
kAwaitingLocalConfirmation)
.build());
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsReceiving(*backend_));
EXPECT_FALSE(BackendTestPeer::IsReceiveTimerActive(*backend_));
}
TEST_F(BackendFastInitiationTest, DiscoveryStopsFastInitiationScanning) {
backend_->startDiscovery();
EXPECT_FALSE(fast_init_manager_.IsScanning());
EXPECT_TRUE(BackendTestPeer::IsIdle(*backend_));
fast_init_manager_.CompleteStop();
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsDiscovering(*backend_));
backend_->startReceive();
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsIdle(*backend_));
EXPECT_TRUE(fast_init_manager_.IsScanning());
}
TEST_F(BackendFastInitiationTest, ScanErrorUsesOneFallbackWindowThenIdles) {
fast_init_manager_.StopScanning(nullptr);
fast_init_manager_.FireError(
nearby::api::FastInitiationManager::Error::kHardwareNotSupported);
DrainEvents();
ASSERT_TRUE(BackendTestPeer::IsReceiving(*backend_));
EXPECT_TRUE(BackendTestPeer::IsReceiveTimerActive(*backend_));
BackendTestPeer::ExpireReceiveWindow(*backend_);
DrainEvents();
EXPECT_TRUE(BackendTestPeer::IsIdle(*backend_));
EXPECT_FALSE(BackendTestPeer::IsMonitoringRequested(*backend_));
EXPECT_FALSE(fast_init_manager_.IsScanning());
}
} // namespace