123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- // 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/hid/fido_hid_discovery.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/containers/contains.h"
- #include "base/no_destructor.h"
- #include "components/device_event_log/device_event_log.h"
- #include "device/fido/hid/fido_hid_device.h"
- namespace device {
- namespace {
- // Checks that the supported report sizes of |device| are sufficient for at
- // least one byte of non-header data per report and not larger than our maximum
- // size.
- bool ReportSizesSufficient(const device::mojom::HidDeviceInfo& device) {
- return device.max_input_report_size > kHidInitPacketHeaderSize &&
- device.max_input_report_size <= kHidMaxPacketSize &&
- device.max_output_report_size > kHidInitPacketHeaderSize &&
- device.max_output_report_size <= kHidMaxPacketSize;
- }
- FidoHidDiscovery::HidManagerBinder& GetHidManagerBinder() {
- static base::NoDestructor<FidoHidDiscovery::HidManagerBinder> binder;
- return *binder;
- }
- } // namespace
- bool operator==(const VidPid& lhs, const VidPid& rhs) {
- return lhs.vid == rhs.vid && lhs.pid == rhs.pid;
- }
- bool operator<(const VidPid& lhs, const VidPid& rhs) {
- return lhs.vid < rhs.vid || (lhs.vid == rhs.vid && lhs.pid < rhs.pid);
- }
- FidoHidDiscovery::FidoHidDiscovery(base::flat_set<VidPid> ignore_list)
- : FidoDeviceDiscovery(FidoTransportProtocol::kUsbHumanInterfaceDevice),
- ignore_list_(std::move(ignore_list)) {
- constexpr uint16_t kFidoUsagePage = 0xf1d0;
- filter_.SetUsagePage(kFidoUsagePage);
- }
- FidoHidDiscovery::~FidoHidDiscovery() = default;
- // static
- void FidoHidDiscovery::SetHidManagerBinder(HidManagerBinder binder) {
- GetHidManagerBinder() = std::move(binder);
- }
- void FidoHidDiscovery::StartInternal() {
- const auto& binder = GetHidManagerBinder();
- if (!binder)
- return;
- binder.Run(hid_manager_.BindNewPipeAndPassReceiver());
- hid_manager_->GetDevicesAndSetClient(
- receiver_.BindNewEndpointAndPassRemote(),
- base::BindOnce(&FidoHidDiscovery::OnGetDevices,
- weak_factory_.GetWeakPtr()));
- }
- void FidoHidDiscovery::DeviceAdded(
- device::mojom::HidDeviceInfoPtr device_info) {
- // The init packet header is the larger of the headers so we only compare
- // against it below.
- static_assert(
- kHidInitPacketHeaderSize >= kHidContinuationPacketHeaderSize,
- "init header is expected to be larger than continuation header");
- if (!filter_.Matches(*device_info) || !ReportSizesSufficient(*device_info)) {
- return;
- }
- const VidPid vid_pid{device_info->vendor_id, device_info->product_id};
- if (base::Contains(ignore_list_, vid_pid)) {
- FIDO_LOG(EVENT) << "Ignoring HID device " << vid_pid.vid << ":"
- << vid_pid.pid;
- return;
- }
- AddDevice(std::make_unique<FidoHidDevice>(std::move(device_info),
- hid_manager_.get()));
- }
- void FidoHidDiscovery::DeviceRemoved(
- device::mojom::HidDeviceInfoPtr device_info) {
- // Ignore non-U2F devices.
- if (filter_.Matches(*device_info)) {
- RemoveDevice(FidoHidDevice::GetIdForDevice(*device_info));
- }
- }
- void FidoHidDiscovery::DeviceChanged(
- device::mojom::HidDeviceInfoPtr device_info) {
- // The changed |device_info| may affect how the device should be filtered.
- // For instance, it may have been updated from a device with no FIDO U2F
- // capabilities to a device with FIDO U2F capabilities.
- //
- // Try adding it again. If the device is already present in |authenticators_|
- // then the updated device will be detected as a duplicate and will not be
- // added.
- //
- // The FidoHidDevice object will retain the old device info. This is fine
- // since it does not rely on any HidDeviceInfo members that could change.
- DeviceAdded(std::move(device_info));
- }
- void FidoHidDiscovery::OnGetDevices(
- std::vector<device::mojom::HidDeviceInfoPtr> device_infos) {
- for (auto& device_info : device_infos)
- DeviceAdded(std::move(device_info));
- NotifyDiscoveryStarted(true);
- }
- } // namespace device
|