zcr_touchpad_haptics.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2021 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. #include "components/exo/wayland/zcr_touchpad_haptics.h"
  5. #include <touchpad-haptics-unstable-v1-server-protocol.h>
  6. #include <wayland-server-core.h>
  7. #include <wayland-server-protocol-core.h>
  8. #include "base/feature_list.h"
  9. #include "base/logging.h"
  10. #include "build/chromeos_buildflags.h"
  11. #include "components/exo/wayland/server_util.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. #include "ui/events/devices/haptic_touchpad_effects.h"
  14. #include "ui/ozone/public/input_controller.h"
  15. #include "ui/ozone/public/ozone_platform.h"
  16. #if BUILDFLAG(IS_CHROMEOS_ASH)
  17. #include "ash/constants/ash_features.h"
  18. #endif
  19. namespace exo {
  20. namespace wayland {
  21. namespace {
  22. class WaylandTouchpadHapticsDelegate {
  23. public:
  24. explicit WaylandTouchpadHapticsDelegate(wl_resource* resource)
  25. : resource_{resource} {}
  26. ~WaylandTouchpadHapticsDelegate() = default;
  27. void UpdateTouchpadHapticsState() {
  28. #if BUILDFLAG(IS_CHROMEOS_ASH)
  29. if (!base::FeatureList::IsEnabled(
  30. chromeos::features::kExoHapticFeedbackSupport))
  31. return;
  32. #endif
  33. ui::InputController* controller =
  34. ui::OzonePlatform::GetInstance()->GetInputController();
  35. if (!controller) {
  36. LOG(ERROR) << "InputController is not available.";
  37. return;
  38. }
  39. if (last_activation_state_ &&
  40. *last_activation_state_ == controller->HasHapticTouchpad()) {
  41. // No need to send the update.
  42. return;
  43. }
  44. last_activation_state_ = controller->HasHapticTouchpad();
  45. if (*last_activation_state_)
  46. zcr_touchpad_haptics_v1_send_activated(resource_);
  47. else
  48. zcr_touchpad_haptics_v1_send_deactivated(resource_);
  49. }
  50. void Play(uint32_t effect, int32_t strength) {
  51. ui::InputController* controller =
  52. ui::OzonePlatform::GetInstance()->GetInputController();
  53. if (!controller) {
  54. LOG(ERROR) << "InputController is not available.";
  55. return;
  56. }
  57. controller->PlayHapticTouchpadEffect(
  58. static_cast<ui::HapticTouchpadEffect>(effect),
  59. static_cast<ui::HapticTouchpadEffectStrength>(strength));
  60. }
  61. private:
  62. wl_resource* const resource_;
  63. absl::optional<bool> last_activation_state_;
  64. };
  65. void touchpad_haptics_destroy(wl_client* client, wl_resource* resource) {
  66. wl_resource_destroy(resource);
  67. }
  68. void touchpad_haptics_play(wl_client* client,
  69. wl_resource* resource,
  70. uint32_t effect,
  71. int32_t strength) {
  72. #if BUILDFLAG(IS_CHROMEOS_ASH)
  73. if (!base::FeatureList::IsEnabled(
  74. chromeos::features::kExoHapticFeedbackSupport))
  75. return;
  76. #endif
  77. GetUserDataAs<WaylandTouchpadHapticsDelegate>(resource)->Play(effect,
  78. strength);
  79. }
  80. const struct zcr_touchpad_haptics_v1_interface touchpad_haptics_implementation =
  81. {
  82. touchpad_haptics_destroy,
  83. touchpad_haptics_play,
  84. };
  85. } // namespace
  86. void bind_touchpad_haptics(wl_client* client,
  87. void* data,
  88. uint32_t version,
  89. uint32_t id) {
  90. wl_resource* resource = wl_resource_create(
  91. client, &zcr_touchpad_haptics_v1_interface, version, id);
  92. SetImplementation(resource, &touchpad_haptics_implementation,
  93. std::make_unique<WaylandTouchpadHapticsDelegate>(resource));
  94. GetUserDataAs<WaylandTouchpadHapticsDelegate>(resource)
  95. ->UpdateTouchpadHapticsState();
  96. }
  97. } // namespace wayland
  98. } // namespace exo