hid_haptic_gamepad.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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_GAMEPAD_HID_HAPTIC_GAMEPAD_H_
  5. #define DEVICE_GAMEPAD_HID_HAPTIC_GAMEPAD_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <memory>
  9. #include "base/memory/weak_ptr.h"
  10. #include "device/gamepad/abstract_haptic_gamepad.h"
  11. #include "device/gamepad/gamepad_export.h"
  12. namespace device {
  13. class HidWriter;
  14. class DEVICE_GAMEPAD_EXPORT HidHapticGamepad final
  15. : public AbstractHapticGamepad {
  16. public:
  17. // Devices that support HID haptic effects with a simple output report can
  18. // be supported through HidHapticGamepad by adding a new HapticReportData
  19. // item to kHapticReportData.
  20. //
  21. // Example:
  22. // { 0x1234, 0xabcd, 0x42, 5, 1, 3, 2 * 8, 0, 0xffff }
  23. // This item recognizes a device 1234:abcd that accepts a 5-byte output report
  24. // containing report ID 0x42 at byte 0 and two 16-bit vibration magnitudes at
  25. // bytes 1:2 and 3:4.
  26. // SetVibration(1.0, 0.5)
  27. // This call describes a vibration effect with 100% intensity on the strong
  28. // actuator and 50% intensity on the weak actuator. For the above device, it
  29. // will scale each magnitude to the [0,0xffff] range when constructing the
  30. // output report. The first value is scaled to 0xffff and the second is scaled
  31. // to 0x7fff.
  32. // uint8_t[] {0x42, 0xff, 0xff, 0xff, 0x7f}
  33. // The above bytes represent the output report data sent to the device. The
  34. // report ID is written to byte 0, the strong magnitude 0xffff is written to
  35. // bytes 1 and 2 in LE-order, and the weak magnitude is written to bytes 3 and
  36. // 4 in LE-order.
  37. struct HapticReportData {
  38. // Supported HID gamepads are identified by their vendor and product IDs.
  39. const uint16_t vendor_id;
  40. const uint16_t product_id;
  41. // The 8-bit report ID value to send at the start of the output report.
  42. // Set to zero if the device does not use report IDs.
  43. const uint8_t report_id;
  44. // The total length of the output report in bytes, including the report ID.
  45. const size_t report_length_bytes;
  46. // The byte offsets of the strong and weak vibration magnitude fields within
  47. // the output report. If |strong_offset_bytes| == |weak_offset_bytes| then
  48. // the device is considered a single-channel haptic actuator. Magnitudes
  49. // from the strong and weak channels will be combined into a single value.
  50. const size_t strong_offset_bytes;
  51. const size_t weak_offset_bytes;
  52. // The width of a vibration magnitude field within the output report. Both
  53. // strong and weak magnitude fields must have the same size. The report size
  54. // must be a multiple of 8. Report fields with size greater than one byte
  55. // will be stored in little-endian byte order.
  56. const size_t report_size_bits;
  57. // The logical extents of the vibration magnitude field, used for scaling
  58. // the vibration value. If |logical_min| == 0 and |logical_max| == 1 then
  59. // the device is considered an "on-off" actuator and any non-zero vibration
  60. // magnitude will cause a vibration effect with maximum intensity.
  61. const uint32_t logical_min;
  62. const uint32_t logical_max;
  63. };
  64. HidHapticGamepad(const HapticReportData& data,
  65. std::unique_ptr<HidWriter> writer);
  66. ~HidHapticGamepad() override;
  67. static std::unique_ptr<HidHapticGamepad> Create(
  68. uint16_t vendor_id,
  69. uint16_t product_id,
  70. std::unique_ptr<HidWriter> writer);
  71. // Return true if the device IDs match an item in kHapticReportData.
  72. static bool IsHidHaptic(uint16_t vendor_id, uint16_t product_id);
  73. // Return the HapticReportData for the device with matching device IDs.
  74. static const HidHapticGamepad::HapticReportData* GetHapticReportData(
  75. uint16_t vendor_id,
  76. uint16_t product_id);
  77. // AbstractHapticGamepad public implementation.
  78. void SetVibration(mojom::GamepadEffectParametersPtr params) override;
  79. base::WeakPtr<AbstractHapticGamepad> GetWeakPtr() override;
  80. private:
  81. // AbstractHapticGamepad private implementation.
  82. void DoShutdown() override;
  83. // Report ID of the report to use for vibration commands, or zero if report
  84. // IDs are not used.
  85. uint8_t report_id_;
  86. // The total size of the report, including the report ID (if any).
  87. size_t report_length_bytes_;
  88. // Byte offsets for the strong and weak magnitude values within the report.
  89. size_t strong_offset_bytes_;
  90. size_t weak_offset_bytes_;
  91. // Width of the vibration magnitude values, in bits.
  92. size_t report_size_bits_;
  93. // Logical bounds of the vibration magnitude. Assumed to be positive.
  94. uint32_t logical_min_;
  95. uint32_t logical_max_;
  96. std::unique_ptr<HidWriter> writer_;
  97. base::WeakPtrFactory<HidHapticGamepad> weak_factory_{this};
  98. };
  99. extern HidHapticGamepad::HapticReportData kHapticReportData[];
  100. extern size_t kHapticReportDataLength;
  101. } // namespace device
  102. #endif // DEVICE_GAMEPAD_HID_HAPTIC_GAMEPAD_H_