Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: ui/chromeos/touch_accessibility_enabler.cc

Issue 2476843003: Toggle spoken feedback if two fingers are held down. (Closed)
Patch Set: Address last nits Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
5 #include "ui/chromeos/touch_accessibility_enabler.h"
6
7 #include <math.h>
8
9 #include <utility>
10
11 #include "base/logging.h"
12 #include "base/time/default_tick_clock.h"
13 #include "ui/aura/window.h"
14 #include "ui/aura/window_event_dispatcher.h"
15 #include "ui/aura/window_tree_host.h"
16 #include "ui/events/event.h"
17 #include "ui/events/event_processor.h"
18 #include "ui/events/event_utils.h"
19
20 namespace ui {
21
22 namespace {
23
24 // Delay between timer callbacks. Each one plays a tick sound.
25 constexpr int kTimerDelayInMS = 500;
26
27 // The number of ticks of the timer before toggling spoken feedback.
28 constexpr int kTimerTicksToToggleSpokenFeedback = 7;
29
30 } // namespace
31
32 TouchAccessibilityEnabler::TouchAccessibilityEnabler(
33 aura::Window* root_window,
34 TouchAccessibilityEnablerDelegate* delegate)
35 : root_window_(root_window),
36 delegate_(delegate),
37 state_(NO_FINGERS_DOWN),
38 tick_clock_(NULL) {
39 DCHECK(root_window);
40 DCHECK(delegate);
41 root_window_->AddPreTargetHandler(this);
42 }
43
44 TouchAccessibilityEnabler::~TouchAccessibilityEnabler() {
45 root_window_->RemovePreTargetHandler(this);
46 }
47
48 void TouchAccessibilityEnabler::OnTouchEvent(ui::TouchEvent* event) {
49 // Skip events rewritten by TouchExplorationController, it will hand
50 // us the unrewritten events directly.
51 if (!(event->flags() & ui::EF_TOUCH_ACCESSIBILITY))
52 HandleTouchEvent(*event);
53 }
54
55 void TouchAccessibilityEnabler::HandleTouchEvent(const ui::TouchEvent& event) {
56 DCHECK(!(event.flags() & ui::EF_TOUCH_ACCESSIBILITY));
57 const ui::EventType type = event.type();
58 const gfx::PointF& location = event.location_f();
59 const int touch_id = event.touch_id();
60
61 if (type == ui::ET_TOUCH_PRESSED) {
62 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
63 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
64 auto iter = touch_locations_.find(touch_id);
65
66 // Can happen if this object is constructed while fingers were down.
67 if (iter == touch_locations_.end())
68 return;
69
70 touch_locations_.erase(touch_id);
71 } else if (type == ui::ET_TOUCH_MOVED) {
72 auto iter = touch_locations_.find(touch_id);
73
74 // Can happen if this object is constructed while fingers were down.
75 if (iter == touch_locations_.end())
76 return;
77
78 float delta = (location - iter->second).Length();
79 if (delta > gesture_detector_config_.double_tap_slop) {
80 state_ = WAIT_FOR_NO_FINGERS;
81 CancelTimer();
82 return;
83 }
84 } else {
85 NOTREACHED() << "Unexpected event type received: " << event.name();
86 return;
87 }
88
89 if (touch_locations_.size() == 0) {
90 state_ = NO_FINGERS_DOWN;
91 CancelTimer();
92 return;
93 }
94
95 if (touch_locations_.size() > 2) {
96 state_ = WAIT_FOR_NO_FINGERS;
97 CancelTimer();
98 return;
99 }
100
101 if (state_ == NO_FINGERS_DOWN && event.type() == ui::ET_TOUCH_PRESSED) {
102 state_ = ONE_FINGER_DOWN;
103 } else if (state_ == ONE_FINGER_DOWN &&
104 event.type() == ui::ET_TOUCH_PRESSED) {
105 state_ = TWO_FINGERS_DOWN;
106 two_finger_start_time_ = Now();
107 StartTimer();
108 }
109 }
110
111 base::TimeTicks TouchAccessibilityEnabler::Now() {
112 if (tick_clock_) {
113 // This is the same as what EventTimeForNow() does, but here we do it
114 // with a clock that can be replaced with a simulated clock for tests.
115 return tick_clock_->NowTicks();
116 }
117 return ui::EventTimeForNow();
118 }
119
120 void TouchAccessibilityEnabler::StartTimer() {
121 if (timer_.IsRunning())
122 return;
123
124 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerDelayInMS),
125 this, &ui::TouchAccessibilityEnabler::OnTimer);
126 }
127
128 void TouchAccessibilityEnabler::CancelTimer() {
129 if (timer_.IsRunning())
130 timer_.Stop();
131 }
132
133 void TouchAccessibilityEnabler::OnTimer() {
134 base::TimeTicks now = Now();
135 double tick_count_f =
136 (now - two_finger_start_time_).InMillisecondsF() / kTimerDelayInMS;
137 int tick_count = roundf(tick_count_f);
138 if (tick_count >= 1 && tick_count < kTimerTicksToToggleSpokenFeedback) {
139 delegate_->PlaySpokenFeedbackToggleCountdown(tick_count);
140 }
141 if (tick_count == kTimerTicksToToggleSpokenFeedback) {
142 delegate_->ToggleSpokenFeedback();
143 state_ = WAIT_FOR_NO_FINGERS;
144 }
145 }
146
147 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_accessibility_enabler.h ('k') | ui/chromeos/touch_accessibility_enabler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698