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