device_operation.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2018 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. #ifndef DEVICE_FIDO_DEVICE_OPERATION_H_
  5. #define DEVICE_FIDO_DEVICE_OPERATION_H_
  6. #include <stdint.h>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/bind.h"
  10. #include "base/callback.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/threading/sequenced_task_runner_handle.h"
  13. #include "device/fido/fido_constants.h"
  14. #include "device/fido/fido_device.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. namespace device {
  17. // GenericDeviceOperation is a base class to allow a |DeviceOperation| to be
  18. // held in |std::unique_ptr| without having to know the concrete type of the
  19. // operation.
  20. class GenericDeviceOperation {
  21. public:
  22. virtual ~GenericDeviceOperation() = default;
  23. virtual void Start() = 0;
  24. // Cancel will attempt to cancel the current operation. It is safe to call
  25. // this function both before |Start| and after the operation has completed.
  26. virtual void Cancel() = 0;
  27. };
  28. template <class Request, class Response>
  29. class DeviceOperation : public GenericDeviceOperation {
  30. public:
  31. using DeviceResponseCallback =
  32. base::OnceCallback<void(CtapDeviceResponseCode,
  33. absl::optional<Response>)>;
  34. // Represents a per device logic that is owned by FidoTask. Thus,
  35. // DeviceOperation does not outlive |request|.
  36. DeviceOperation(FidoDevice* device,
  37. Request request,
  38. DeviceResponseCallback callback)
  39. : device_(device),
  40. request_(std::move(request)),
  41. callback_(std::move(callback)) {}
  42. DeviceOperation(const DeviceOperation&) = delete;
  43. DeviceOperation& operator=(const DeviceOperation&) = delete;
  44. ~DeviceOperation() override = default;
  45. protected:
  46. void DispatchU2FCommand(absl::optional<std::vector<uint8_t>> command,
  47. FidoDevice::DeviceCallback callback) {
  48. if (!command || device_->is_in_error_state()) {
  49. base::SequencedTaskRunnerHandle::Get()->PostTask(
  50. FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
  51. return;
  52. }
  53. token_ = device_->DeviceTransact(std::move(*command), std::move(callback));
  54. }
  55. const Request& request() const { return request_; }
  56. FidoDevice* device() const { return device_; }
  57. DeviceResponseCallback callback() { return std::move(callback_); }
  58. absl::optional<FidoDevice::CancelToken> token_;
  59. private:
  60. const raw_ptr<FidoDevice> device_ = nullptr;
  61. Request request_;
  62. DeviceResponseCallback callback_;
  63. };
  64. } // namespace device
  65. #endif // DEVICE_FIDO_DEVICE_OPERATION_H_