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

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

Issue 2476843003: Toggle spoken feedback if two fingers are held down. (Closed)
Patch Set: 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 <utility>
8
9 #include "base/logging.h"
10 #include "base/time/default_tick_clock.h"
11 #include "ui/aura/window.h"
12 #include "ui/aura/window_event_dispatcher.h"
13 #include "ui/aura/window_tree_host.h"
14 #include "ui/events/event.h"
15 #include "ui/events/event_processor.h"
16 #include "ui/events/event_utils.h"
17
18 namespace ui {
19
20 namespace {
21
22 // Delay between timer callbacks. Each one plays a tick sound.
23 const int kTimerDelayInMS = 500;
oshima 2016/11/08 18:14:43 nit: constexpr
dmazzoni 2016/11/08 20:43:47 Done.
24
25 // The number of ticks of the timer before toggling spoken feedback.
26 const int kTimerTicksToToggleSpokenFeedback = 7;
27
28 } // namespace
29
30 TouchAccessibilityEnabler::TouchAccessibilityEnabler(
31 aura::Window* root_window,
32 TouchAccessibilityEnablerDelegate* delegate)
33 : root_window_(root_window),
34 delegate_(delegate),
35 state_(NO_FINGERS_DOWN),
36 tick_clock_(NULL) {
37 DCHECK(root_window);
oshima 2016/11/08 18:14:43 delegate too?
dmazzoni 2016/11/08 20:43:47 Done.
38 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
39 }
40
41 TouchAccessibilityEnabler::~TouchAccessibilityEnabler() {
42 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
43 }
44
45 ui::EventRewriteStatus TouchAccessibilityEnabler::RewriteEvent(
46 const ui::Event& event,
47 std::unique_ptr<ui::Event>* rewritten_event) {
oshima 2016/11/08 18:14:43 so eventhandler doesn't work?
dmazzoni 2016/11/08 20:43:47 Oh, good catch! Originally I did rewrite an event
dmazzoni 2016/11/08 21:18:04 Actually after testing some more, it doesn't work
sadrul 2016/11/10 20:39:03 I would like to understand more, because this is a
48 if (!event.IsTouchEvent())
49 return ui::EVENT_REWRITE_CONTINUE;
50
51 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event);
52 HandleTouchEvent(touch_event);
53 return ui::EVENT_REWRITE_CONTINUE;
54 }
55
56 ui::EventRewriteStatus TouchAccessibilityEnabler::NextDispatchEvent(
57 const ui::Event& last_event,
58 std::unique_ptr<ui::Event>* new_event) {
59 NOTREACHED();
60 return ui::EVENT_REWRITE_CONTINUE;
61 }
62
63 void TouchAccessibilityEnabler::HandleTouchEvent(const ui::TouchEvent& event) {
64 const ui::EventType type = event.type();
65 const gfx::PointF& location = event.location_f();
66 const int touch_id = event.touch_id();
67
68 if (type == ui::ET_TOUCH_PRESSED) {
69 touch_ids_.push_back(touch_id);
70 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
71 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
72 auto iter = std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
73
74 // Can happen if this object is constructed while fingers were down.
75 if (iter == touch_ids_.end())
76 return;
77
78 touch_ids_.erase(iter);
79 touch_locations_.erase(touch_id);
80 } else if (type == ui::ET_TOUCH_MOVED) {
81 auto iter = std::find(touch_ids_.begin(), touch_ids_.end(), touch_id);
82
83 // Can happen if this object is constructed while fingers were down.
84 if (iter == touch_ids_.end())
85 return;
86
87 float delta = (location - touch_locations_[*iter]).Length();
88 if (delta > gesture_detector_config_.double_tap_slop) {
89 state_ = WAIT_FOR_NO_FINGERS;
90 CancelTimer();
91 return;
92 }
93 } else {
94 NOTREACHED() << "Unexpected event type received: " << event.name();
95 return;
96 }
97
98 if (touch_ids_.size() == 0) {
99 state_ = NO_FINGERS_DOWN;
100 CancelTimer();
101 return;
102 }
103
104 if (touch_ids_.size() > 2) {
105 state_ = WAIT_FOR_NO_FINGERS;
106 CancelTimer();
107 return;
108 }
109
110 if (state_ == NO_FINGERS_DOWN && event.type() == ui::ET_TOUCH_PRESSED) {
111 state_ = ONE_FINGER_DOWN;
112 } else if (state_ == ONE_FINGER_DOWN &&
113 event.type() == ui::ET_TOUCH_PRESSED) {
114 state_ = TWO_FINGERS_DOWN;
115 two_finger_start_time_ = Now();
116 StartTimer();
117 }
118 }
119
120 base::TimeTicks TouchAccessibilityEnabler::Now() {
121 if (tick_clock_) {
122 // This is the same as what EventTimeForNow() does, but here we do it
123 // with a clock that can be replaced with a simulated clock for tests.
124 return tick_clock_->NowTicks();
125 }
126 return ui::EventTimeForNow();
127 }
128
129 void TouchAccessibilityEnabler::StartTimer() {
130 if (timer_.IsRunning())
131 return;
132
133 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerDelayInMS),
134 this, &ui::TouchAccessibilityEnabler::OnTimer);
135 }
136
137 void TouchAccessibilityEnabler::CancelTimer() {
138 if (timer_.IsRunning())
139 timer_.Stop();
140 }
141
142 void TouchAccessibilityEnabler::OnTimer() {
143 base::TimeTicks now = Now();
144 double tick_count_f =
145 (now - two_finger_start_time_).InMillisecondsF() / kTimerDelayInMS;
146 int tick_count = roundf(tick_count_f);
147 if (tick_count >= 1 && tick_count < kTimerTicksToToggleSpokenFeedback) {
148 delegate_->PlaySpokenFeedbackToggleCountdown(tick_count);
149 }
150 if (tick_count == kTimerTicksToToggleSpokenFeedback) {
151 delegate_->ToggleSpokenFeedback();
152 state_ = WAIT_FOR_NO_FINGERS;
153 }
154 }
155
156 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698