fido_device_discovery.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "device/fido/fido_device_discovery.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/threading/sequenced_task_runner_handle.h"
  8. #include "device/fido/fido_authenticator.h"
  9. #include "device/fido/fido_device.h"
  10. #include "device/fido/fido_device_authenticator.h"
  11. namespace device {
  12. FidoDeviceDiscovery::Observer::~Observer() = default;
  13. FidoDeviceDiscovery::FidoDeviceDiscovery(FidoTransportProtocol transport)
  14. : FidoDiscoveryBase(transport) {}
  15. FidoDeviceDiscovery::~FidoDeviceDiscovery() = default;
  16. void FidoDeviceDiscovery::Start() {
  17. DCHECK_EQ(state_, State::kIdle);
  18. state_ = State::kStarting;
  19. // To ensure that that NotifyStarted() is never invoked synchronously,
  20. // post task asynchronously.
  21. base::SequencedTaskRunnerHandle::Get()->PostTask(
  22. FROM_HERE, base::BindOnce(&FidoDeviceDiscovery::StartInternal,
  23. weak_factory_.GetWeakPtr()));
  24. }
  25. void FidoDeviceDiscovery::NotifyDiscoveryStarted(bool success) {
  26. if (state_ == State::kStopped)
  27. return;
  28. DCHECK(state_ == State::kStarting);
  29. if (success)
  30. state_ = State::kRunning;
  31. if (!observer())
  32. return;
  33. std::vector<FidoAuthenticator*> authenticators;
  34. authenticators.reserve(authenticators_.size());
  35. for (const auto& authenticator : authenticators_)
  36. authenticators.push_back(authenticator.second.get());
  37. observer()->DiscoveryStarted(this, success, std::move(authenticators));
  38. }
  39. void FidoDeviceDiscovery::NotifyAuthenticatorAdded(
  40. FidoAuthenticator* authenticator) {
  41. DCHECK_NE(state_, State::kIdle);
  42. if (!observer() || state_ != State::kRunning)
  43. return;
  44. observer()->AuthenticatorAdded(this, authenticator);
  45. }
  46. void FidoDeviceDiscovery::NotifyAuthenticatorRemoved(
  47. FidoAuthenticator* authenticator) {
  48. DCHECK_NE(state_, State::kIdle);
  49. if (!observer() || state_ != State::kRunning)
  50. return;
  51. observer()->AuthenticatorRemoved(this, authenticator);
  52. }
  53. std::vector<FidoDeviceAuthenticator*>
  54. FidoDeviceDiscovery::GetAuthenticatorsForTesting() {
  55. std::vector<FidoDeviceAuthenticator*> authenticators;
  56. authenticators.reserve(authenticators_.size());
  57. for (const auto& authenticator : authenticators_)
  58. authenticators.push_back(authenticator.second.get());
  59. return authenticators;
  60. }
  61. std::vector<const FidoDeviceAuthenticator*>
  62. FidoDeviceDiscovery::GetAuthenticatorsForTesting() const {
  63. std::vector<const FidoDeviceAuthenticator*> authenticators;
  64. authenticators.reserve(authenticators_.size());
  65. for (const auto& authenticator : authenticators_)
  66. authenticators.push_back(authenticator.second.get());
  67. return authenticators;
  68. }
  69. FidoDeviceAuthenticator* FidoDeviceDiscovery::GetAuthenticatorForTesting(
  70. base::StringPiece authenticator_id) {
  71. return GetAuthenticator(authenticator_id);
  72. }
  73. FidoDeviceAuthenticator* FidoDeviceDiscovery::GetAuthenticator(
  74. base::StringPiece authenticator_id) {
  75. auto found = authenticators_.find(authenticator_id);
  76. return found != authenticators_.end() ? found->second.get() : nullptr;
  77. }
  78. bool FidoDeviceDiscovery::AddDevice(std::unique_ptr<FidoDevice> device) {
  79. return AddAuthenticator(
  80. std::make_unique<FidoDeviceAuthenticator>(std::move(device)));
  81. }
  82. bool FidoDeviceDiscovery::AddAuthenticator(
  83. std::unique_ptr<FidoDeviceAuthenticator> authenticator) {
  84. if (state_ == State::kStopped)
  85. return false;
  86. std::string authenticator_id = authenticator->GetId();
  87. const auto result = authenticators_.emplace(std::move(authenticator_id),
  88. std::move(authenticator));
  89. if (!result.second) {
  90. return false; // Duplicate device id.
  91. }
  92. NotifyAuthenticatorAdded(result.first->second.get());
  93. return true;
  94. }
  95. bool FidoDeviceDiscovery::RemoveDevice(base::StringPiece device_id) {
  96. if (state_ == State::kStopped)
  97. return false;
  98. auto found = authenticators_.find(device_id);
  99. if (found == authenticators_.end())
  100. return false;
  101. auto authenticator = std::move(found->second);
  102. authenticators_.erase(found);
  103. NotifyAuthenticatorRemoved(authenticator.get());
  104. return true;
  105. }
  106. bool FidoDeviceDiscovery::MaybeStop() {
  107. state_ = State::kStopped;
  108. return true;
  109. }
  110. } // namespace device