gamepad_device_linux.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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_GAMEPAD_DEVICE_LINUX_H_
  5. #define DEVICE_GAMEPAD_GAMEPAD_DEVICE_LINUX_H_
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. #include "base/files/scoped_file.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "device/gamepad/abstract_haptic_gamepad.h"
  12. #include "device/gamepad/gamepad_id_list.h"
  13. #include "device/gamepad/gamepad_standard_mappings.h"
  14. #include "device/gamepad/udev_gamepad_linux.h"
  15. extern "C" {
  16. struct udev_device;
  17. }
  18. namespace device {
  19. class Dualshock4Controller;
  20. class HidHapticGamepad;
  21. class XboxHidController;
  22. // GamepadDeviceLinux represents a single gamepad device which may be accessed
  23. // through multiple host interfaces. Gamepad button and axis state are queried
  24. // through the joydev interface, while haptics commands are routed through the
  25. // evdev interface. A gamepad must be enumerated through joydev to be usable,
  26. // but the evdev interface is only required for haptic effects.
  27. //
  28. // For some devices, haptics are not supported through evdev and are instead
  29. // sent through the raw HID (hidraw) interface.
  30. class GamepadDeviceLinux final : public AbstractHapticGamepad {
  31. public:
  32. using OpenDeviceNodeCallback = base::OnceCallback<void(GamepadDeviceLinux*)>;
  33. GamepadDeviceLinux(const std::string& syspath_prefix,
  34. scoped_refptr<base::SequencedTaskRunner> dbus_runner);
  35. ~GamepadDeviceLinux() override;
  36. // Returns true if no device nodes are associated with this device.
  37. bool IsEmpty() const;
  38. int GetJoydevIndex() const { return joydev_index_; }
  39. uint16_t GetVendorId() const { return vendor_id_; }
  40. uint16_t GetProductId() const { return product_id_; }
  41. uint16_t GetVersionNumber() const { return version_number_; }
  42. std::string GetName() const { return name_; }
  43. std::string GetSyspathPrefix() const { return syspath_prefix_; }
  44. GamepadBusType GetBusType() const { return bus_type_; }
  45. GamepadStandardMappingFunction GetMappingFunction() const;
  46. bool SupportsVibration() const;
  47. // Reads the current gamepad state into |pad|.
  48. void ReadPadState(Gamepad* pad);
  49. // Reads the state of gamepad buttons and axes using joydev. Returns true if
  50. // |pad| was updated.
  51. bool ReadJoydevState(Gamepad* pad);
  52. // Discovers and assigns button indices for key codes that are outside the
  53. // normal gamepad button range.
  54. void InitializeEvdevSpecialKeys();
  55. // Reads the state of keys outside the normal button range using evdev.
  56. // Returns true if |pad| was updated.
  57. bool ReadEvdevSpecialKeys(Gamepad* pad);
  58. // Returns true if |pad_info| describes this device.
  59. bool IsSameDevice(const UdevGamepadLinux& pad_info);
  60. // Opens the joydev device node and queries device info.
  61. bool OpenJoydevNode(const UdevGamepadLinux& pad_info, udev_device* device);
  62. // Closes the joydev device node and clears device info.
  63. void CloseJoydevNode();
  64. // Opens the evdev device node and initializes haptics.
  65. bool OpenEvdevNode(const UdevGamepadLinux& pad_info);
  66. // Closes the evdev device node and shuts down haptics.
  67. void CloseEvdevNode();
  68. // Opens the hidraw device node and initializes haptics.
  69. void OpenHidrawNode(const UdevGamepadLinux& pad_info,
  70. OpenDeviceNodeCallback callback);
  71. // Closes the hidraw device node and shuts down haptics.
  72. void CloseHidrawNode();
  73. // AbstractHapticGamepad public implementation.
  74. void SetVibration(mojom::GamepadEffectParametersPtr params) override;
  75. void SetZeroVibration() override;
  76. base::WeakPtr<AbstractHapticGamepad> GetWeakPtr() override;
  77. private:
  78. // AbstractHapticGamepad private implementation.
  79. void DoShutdown() override;
  80. void OnOpenHidrawNodeComplete(OpenDeviceNodeCallback callback,
  81. base::ScopedFD fd);
  82. void InitializeHidraw(base::ScopedFD fd);
  83. // The syspath prefix is used to identify device nodes that refer to the same
  84. // underlying gamepad through different interfaces.
  85. //
  86. // Joydev and evdev nodes that refer to the same device will share a parent
  87. // node that represents the physical device. We can compare the syspaths of
  88. // the parent nodes to determine when two nodes refer to the same device.
  89. //
  90. // The syspath for a hidraw node will match the parent syspath of a joydev or
  91. // evdev node up to the subsystem. To simplify this comparison, we only store
  92. // the syspath prefix up to the subsystem.
  93. std::string syspath_prefix_;
  94. // The file descriptor for the device's joydev node.
  95. base::ScopedFD joydev_fd_;
  96. // The index of the device's joydev node, or -1 if unknown.
  97. // The joydev index is the integer at the end of the joydev node path and is
  98. // used to assign the gamepad to a slot. For example, a device with path
  99. // /dev/input/js2 has index 2 and will be assigned to the 3rd gamepad slot.
  100. int joydev_index_ = -1;
  101. // Maps from indices in the Gamepad buttons array to a boolean value
  102. // indicating whether the button index is already mapped.
  103. std::vector<bool> button_indices_used_;
  104. // An identifier for the gamepad device model.
  105. GamepadId gamepad_id_ = GamepadId::kUnknownGamepad;
  106. // The vendor ID of the device.
  107. uint16_t vendor_id_;
  108. // The product ID of the device.
  109. uint16_t product_id_;
  110. // The version of the HID specification that this device is compliant with.
  111. // The hid-sony driver patches this value to indicate that a newer mapping has
  112. // been applied.
  113. uint16_t hid_specification_version_;
  114. // The version number of the device.
  115. uint16_t version_number_;
  116. // A string identifying the manufacturer and model of the device.
  117. std::string name_;
  118. // The file descriptor for the device's evdev node.
  119. base::ScopedFD evdev_fd_;
  120. // The ID of the haptic effect stored on the device, or -1 if none is stored.
  121. int effect_id_ = -1;
  122. // True if the device supports rumble effects through the evdev device node.
  123. bool supports_force_feedback_ = false;
  124. // Set to true once the evdev button capabilities have been checked.
  125. bool evdev_special_keys_initialized_ = false;
  126. // Mapping from "special" index (an index within the kSpecialKeys table) to
  127. // button index (an index within the Gamepad buttons array), or -1 if the
  128. // button is not mapped. Empty if no special buttons are mapped.
  129. std::vector<int> special_button_map_;
  130. // The file descriptor for the device's hidraw node.
  131. base::ScopedFD hidraw_fd_;
  132. // The type of the bus through which the device is connected, or
  133. // GAMEPAD_BUS_UNKNOWN if the bus type could not be determined.
  134. GamepadBusType bus_type_ = GAMEPAD_BUS_UNKNOWN;
  135. // Dualshock4 functionality, if available.
  136. std::unique_ptr<Dualshock4Controller> dualshock4_;
  137. // Xbox Wireless Controller behaves like a HID gamepad when connected over
  138. // Bluetooth. In this mode, haptics functionality is provided by |xbox_hid_|.
  139. // When connected over USB, Xbox Wireless Controller is supported through the
  140. // platform driver (xpad).
  141. std::unique_ptr<XboxHidController> xbox_hid_;
  142. // A controller that uses a HID output report for vibration effects.
  143. std::unique_ptr<HidHapticGamepad> hid_haptics_;
  144. // Task runner to use for D-Bus tasks. D-Bus client classes (including
  145. // PermissionBrokerClient) are not thread-safe and should be used only on the
  146. // UI thread.
  147. scoped_refptr<base::SequencedTaskRunner> dbus_runner_;
  148. // Task runner to use for gamepad polling.
  149. scoped_refptr<base::SequencedTaskRunner> polling_runner_;
  150. // Weak pointer factory for use only on the |polling_runner_| thread.
  151. base::WeakPtrFactory<GamepadDeviceLinux> weak_factory_{this};
  152. };
  153. } // namespace device
  154. #endif // DEVICE_GAMEPAD_GAMEPAD_DEVICE_LINUX_H_