touch_accessibility_enabler.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2016 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 ASH_ACCESSIBILITY_CHROMEVOX_TOUCH_ACCESSIBILITY_ENABLER_H_
  5. #define ASH_ACCESSIBILITY_CHROMEVOX_TOUCH_ACCESSIBILITY_ENABLER_H_
  6. #include <map>
  7. #include "ash/ash_export.h"
  8. #include "base/memory/weak_ptr.h"
  9. #include "base/time/tick_clock.h"
  10. #include "base/time/time.h"
  11. #include "base/timer/timer.h"
  12. #include "ui/events/event.h"
  13. #include "ui/events/event_handler.h"
  14. #include "ui/events/gesture_detection/gesture_detector.h"
  15. namespace aura {
  16. class Window;
  17. }
  18. namespace ash {
  19. // A delegate to handle commands in response to detected accessibility gesture
  20. // events.
  21. class TouchAccessibilityEnablerDelegate {
  22. public:
  23. virtual ~TouchAccessibilityEnablerDelegate() {}
  24. // Called when we first detect two fingers are held down.
  25. virtual void OnTwoFingerTouchStart() {}
  26. // Called when the user is no longer holding down two fingers (including
  27. // releasing one, holding down three, or moving them).
  28. virtual void OnTwoFingerTouchStop() {}
  29. // While the user holds down two fingers on a touch screen, which is the
  30. // gesture to enable spoken feedback (if held down long enough), play a sound
  31. // every "tick" (approximately every half-second) to warn the user something
  32. // is about to happen.
  33. virtual void PlaySpokenFeedbackToggleCountdown(int tick_count) {}
  34. // Toggles spoken feedback.
  35. virtual void ToggleSpokenFeedback() {}
  36. };
  37. // TouchAccessibilityEnabler triggers turning spoken feedback on or off
  38. // by holding down two fingers on the touch screen for several seconds.
  39. class ASH_EXPORT TouchAccessibilityEnabler : public ui::EventHandler {
  40. public:
  41. TouchAccessibilityEnabler(aura::Window* root_window,
  42. TouchAccessibilityEnablerDelegate* delegate);
  43. TouchAccessibilityEnabler(const TouchAccessibilityEnabler&) = delete;
  44. TouchAccessibilityEnabler& operator=(const TouchAccessibilityEnabler&) =
  45. delete;
  46. ~TouchAccessibilityEnabler() override;
  47. bool IsInNoFingersDownForTesting() { return state_ == NO_FINGERS_DOWN; }
  48. bool IsInOneFingerDownForTesting() { return state_ == ONE_FINGER_DOWN; }
  49. bool IsInTwoFingersDownForTesting() { return state_ == TWO_FINGERS_DOWN; }
  50. bool IsInWaitForNoFingersForTesting() {
  51. return state_ == WAIT_FOR_NO_FINGERS;
  52. }
  53. void TriggerOnTimerForTesting() { OnTimer(); }
  54. // When TouchExplorationController is running, it tells this class to
  55. // remove its event handler so that it can pass it the unrewritten events
  56. // directly. Otherwise, this class would only receive the rewritten events,
  57. // which would require entirely separate logic.
  58. void RemoveEventHandler();
  59. void AddEventHandler();
  60. void HandleTouchEvent(const ui::TouchEvent& event);
  61. // Expose a weak ptr so that TouchExplorationController can hold a reference
  62. // to this object without worrying about destruction order during shutdown.
  63. base::WeakPtr<TouchAccessibilityEnabler> GetWeakPtr();
  64. private:
  65. // Overridden from ui::EventHandler
  66. void OnTouchEvent(ui::TouchEvent* event) override;
  67. void StartTimer();
  68. void CancelTimer();
  69. void OnTimer();
  70. void ResetToNoFingersDown();
  71. // Returns the current time of the tick clock.
  72. base::TimeTicks Now();
  73. enum State {
  74. // No fingers are down.
  75. NO_FINGERS_DOWN,
  76. // One finger is down and it's possible this could be a two-finger-hold.
  77. ONE_FINGER_DOWN,
  78. // Two fingers are down and stationary and we will trigger enabling
  79. // spoken feedback after a delay.
  80. TWO_FINGERS_DOWN,
  81. // This is the "reject" state when we get anything other than two fingers
  82. // held down and stationary. Stay in this state until all fingers are
  83. // removed.
  84. WAIT_FOR_NO_FINGERS
  85. };
  86. aura::Window* root_window_;
  87. // Called when we detect a long-press of two fingers. Not owned.
  88. TouchAccessibilityEnablerDelegate* delegate_;
  89. // The current state.
  90. State state_;
  91. // The time when we entered the two finger state.
  92. base::TimeTicks two_finger_start_time_;
  93. // Map of touch ids to their initial locations.
  94. std::map<int, gfx::PointF> touch_locations_;
  95. // A timer that triggers repeatedly while two fingers are held down.
  96. base::RepeatingTimer timer_;
  97. // A default gesture detector config, so we can share the same
  98. // timeout and pixel slop constants.
  99. ui::GestureDetector::Config gesture_detector_config_;
  100. // When touch_accessibility_enabler gets time relative to real time during
  101. // testing, this clock is set to the simulated clock and used.
  102. const base::TickClock* tick_clock_;
  103. // Whether or not we currently have an event handler installed. It can
  104. // be removed when TouchExplorationController is running.
  105. bool event_handler_installed_ = false;
  106. base::WeakPtrFactory<TouchAccessibilityEnabler> weak_factory_{this};
  107. };
  108. } // namespace ash
  109. #endif // ASH_ACCESSIBILITY_CHROMEVOX_TOUCH_ACCESSIBILITY_ENABLER_H_