Commit a3d2c434 authored by Yuichiro Hanada's avatar Yuichiro Hanada Committed by Commit Bot

Migrate EventRewriterChromeOS to new API (5/n).

This CL changes RewriteKeyEventInContext to use the new API.
Before this CL, EventRewriterChromeOS::NextDispatchEvent sends the
events from StickyKeysControllers and the events generated in
RewriteKeyEventInContext. Now, RewriteKeyEventInContext takes
Continuation as an argument and sends all generated events without
storing them in dispatched_key_events_ and gets events from
StickyKeysController if it has pending events.
As the result, we can remove dispatched_key_events_ field and
EventRewriterChromeOS::NextDispatchEvent.
However, EventRewriteStatus is still used inside EventRewriterChromeOS,
so we can't clean up them yet.

Bug: 1049489
Test: unit_tests
Change-Id: I41109afa57bc1407beab6ab264bcbfc992d9f1ef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2056526
Commit-Queue: Yuichiro Hanada <yhanada@chromium.org>
Reviewed-by: default avatarMitsuru Oshima (OOO) <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743440}
parent cc41d132
...@@ -496,7 +496,6 @@ void EventRewriterChromeOS::KeyboardDeviceAddedForTesting( ...@@ -496,7 +496,6 @@ void EventRewriterChromeOS::KeyboardDeviceAddedForTesting(
void EventRewriterChromeOS::ResetStateForTesting() { void EventRewriterChromeOS::ResetStateForTesting() {
pressed_key_states_.clear(); pressed_key_states_.clear();
dispatched_key_events_.clear();
pressed_modifier_latches_ = latched_modifier_latches_ = pressed_modifier_latches_ = latched_modifier_latches_ =
used_modifier_latches_ = ui::EF_NONE; used_modifier_latches_ = ui::EF_NONE;
...@@ -511,6 +510,15 @@ void EventRewriterChromeOS::RewriteMouseButtonEventForTesting( ...@@ -511,6 +510,15 @@ void EventRewriterChromeOS::RewriteMouseButtonEventForTesting(
ui::EventDispatchDetails EventRewriterChromeOS::RewriteEvent( ui::EventDispatchDetails EventRewriterChromeOS::RewriteEvent(
const ui::Event& event, const ui::Event& event,
const Continuation continuation) { const Continuation continuation) {
if ((event.type() == ui::ET_KEY_PRESSED) ||
(event.type() == ui::ET_KEY_RELEASED)) {
std::unique_ptr<ui::Event> rewritten_event;
ui::EventRewriteStatus status =
RewriteKeyEvent(*((&event)->AsKeyEvent()), &rewritten_event);
return RewriteKeyEventInContext(*((&event)->AsKeyEvent()),
std::move(rewritten_event), status,
continuation);
}
if ((event.type() == ui::ET_MOUSE_PRESSED) || if ((event.type() == ui::ET_MOUSE_PRESSED) ||
(event.type() == ui::ET_MOUSE_RELEASED)) { (event.type() == ui::ET_MOUSE_RELEASED)) {
return RewriteMouseButtonEvent(static_cast<const ui::MouseEvent&>(event), return RewriteMouseButtonEvent(static_cast<const ui::MouseEvent&>(event),
...@@ -530,46 +538,7 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteEvent( ...@@ -530,46 +538,7 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteEvent(
continuation); continuation);
} }
// The default implementation calls the old RewriteEvent() method below. return SendEvent(continuation, &event);
return ui::EventRewriter::RewriteEvent(event, continuation);
}
ui::EventRewriteStatus EventRewriterChromeOS::RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) {
if ((event.type() == ui::ET_KEY_PRESSED) ||
(event.type() == ui::ET_KEY_RELEASED)) {
ui::EventRewriteStatus status =
RewriteKeyEvent(*((&event)->AsKeyEvent()), rewritten_event);
RewriteKeyEventInContext(*((&event)->AsKeyEvent()), rewritten_event,
&status);
return status;
}
return ui::EVENT_REWRITE_CONTINUE;
}
ui::EventRewriteStatus EventRewriterChromeOS::NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) {
if (dispatched_key_events_.size()) {
*new_event = std::move(dispatched_key_events_.back());
dispatched_key_events_.pop_back();
if (dispatched_key_events_.size())
return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
return ui::EVENT_REWRITE_REWRITTEN;
}
if (sticky_keys_controller_) {
// In the case of sticky keys, we know what the events obtained here are:
// modifier key releases that match the ones previously discarded. So, we
// know that they don't have to be passed through the post-sticky key
// rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|,
// because those phases do nothing with modifier key releases.
return sticky_keys_controller_->NextDispatchEvent(last_event, new_event);
}
NOTREACHED();
return ui::EVENT_REWRITE_CONTINUE;
} }
void EventRewriterChromeOS::BuildRewrittenKeyEvent( void EventRewriterChromeOS::BuildRewrittenKeyEvent(
...@@ -1022,15 +991,12 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteMouseButtonEvent( ...@@ -1022,15 +991,12 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteMouseButtonEvent(
ui::EventDispatchDetails details = ui::EventDispatchDetails details =
SendEventFinally(continuation, rewritten_event.get()); SendEventFinally(continuation, rewritten_event.get());
while (status == ui::EVENT_REWRITE_DISPATCH_ANOTHER && if (status == ui::EVENT_REWRITE_DISPATCH_ANOTHER &&
!details.dispatcher_destroyed) { !details.dispatcher_destroyed) {
// Here, we know that another event is a modifier key release event from // Here, we know that another event is a modifier key release event from
// StickyKeysController. // StickyKeysController.
std::unique_ptr<ui::Event> new_event; return SendStickyKeysReleaseEvents(std::move(rewritten_event),
status = sticky_keys_controller_->NextDispatchEvent(*rewritten_event, continuation);
&new_event);
details = SendEventFinally(continuation, new_event.get());
rewritten_event = std::move(new_event);
} }
return details; return details;
} }
...@@ -1064,13 +1030,11 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteMouseWheelEvent( ...@@ -1064,13 +1030,11 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteMouseWheelEvent(
ui::EventDispatchDetails details = ui::EventDispatchDetails details =
SendEventFinally(continuation, rewritten_event.get()); SendEventFinally(continuation, rewritten_event.get());
while (status == ui::EVENT_REWRITE_DISPATCH_ANOTHER &&
!details.dispatcher_destroyed) { if (status == ui::EVENT_REWRITE_DISPATCH_ANOTHER &&
std::unique_ptr<ui::Event> new_event; !details.dispatcher_destroyed) {
status = sticky_keys_controller_->NextDispatchEvent(*rewritten_event, return SendStickyKeysReleaseEvents(std::move(rewritten_event),
&new_event); continuation);
details = SendEventFinally(continuation, new_event.get());
rewritten_event = std::move(new_event);
} }
return details; return details;
} }
...@@ -1105,13 +1069,10 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteScrollEvent( ...@@ -1105,13 +1069,10 @@ ui::EventDispatchDetails EventRewriterChromeOS::RewriteScrollEvent(
ui::EventDispatchDetails details = ui::EventDispatchDetails details =
SendEventFinally(continuation, rewritten_event.get()); SendEventFinally(continuation, rewritten_event.get());
while (status == ui::EVENT_REWRITE_DISPATCH_ANOTHER && if (status == ui::EVENT_REWRITE_DISPATCH_ANOTHER &&
!details.dispatcher_destroyed) { !details.dispatcher_destroyed) {
std::unique_ptr<ui::Event> new_event; return SendStickyKeysReleaseEvents(std::move(rewritten_event),
status = sticky_keys_controller_->NextDispatchEvent(*rewritten_event, continuation);
&new_event);
details = SendEventFinally(continuation, new_event.get());
rewritten_event = std::move(new_event);
} }
return details; return details;
} }
...@@ -1487,14 +1448,13 @@ int EventRewriterChromeOS::RewriteModifierClick( ...@@ -1487,14 +1448,13 @@ int EventRewriterChromeOS::RewriteModifierClick(
return ui::EF_NONE; return ui::EF_NONE;
} }
void EventRewriterChromeOS::RewriteKeyEventInContext( ui::EventDispatchDetails EventRewriterChromeOS::RewriteKeyEventInContext(
const ui::KeyEvent& key_event, const ui::KeyEvent& key_event,
std::unique_ptr<ui::Event>* rewritten_event, std::unique_ptr<ui::Event> rewritten_event,
ui::EventRewriteStatus* status) { ui::EventRewriteStatus status,
DCHECK(status); const Continuation continuation) {
if (status == EventRewriteStatus::EVENT_REWRITE_DISCARD)
if (*status == EventRewriteStatus::EVENT_REWRITE_DISCARD) return DiscardEvent(continuation);
return;
MutableKeyState current_key_state; MutableKeyState current_key_state;
auto key_state_comparator = auto key_state_comparator =
...@@ -1509,8 +1469,8 @@ void EventRewriterChromeOS::RewriteKeyEventInContext( ...@@ -1509,8 +1469,8 @@ void EventRewriterChromeOS::RewriteKeyEventInContext(
if (key_event.type() == ET_KEY_PRESSED) { if (key_event.type() == ET_KEY_PRESSED) {
current_key_state = MutableKeyState( current_key_state = MutableKeyState(
rewritten_event->get() rewritten_event
? static_cast<const ui::KeyEvent*>(rewritten_event->get()) ? static_cast<const ui::KeyEvent*>(rewritten_event.get())
: &key_event); : &key_event);
MutableKeyState original_key_state(&key_event); MutableKeyState original_key_state(&key_event);
auto iter = std::find_if(pressed_key_states_.begin(), auto iter = std::find_if(pressed_key_states_.begin(),
...@@ -1523,7 +1483,17 @@ void EventRewriterChromeOS::RewriteKeyEventInContext( ...@@ -1523,7 +1483,17 @@ void EventRewriterChromeOS::RewriteKeyEventInContext(
std::make_pair(current_key_state, original_key_state)); std::make_pair(current_key_state, original_key_state));
} }
return; if (status == EventRewriteStatus::EVENT_REWRITE_CONTINUE)
return SendEvent(continuation, &key_event);
ui::EventDispatchDetails details =
SendEventFinally(continuation, rewritten_event.get());
if (status == EventRewriteStatus::EVENT_REWRITE_DISPATCH_ANOTHER &&
!details.dispatcher_destroyed) {
return SendStickyKeysReleaseEvents(std::move(rewritten_event),
continuation);
}
return details;
} }
DCHECK_EQ(key_event.type(), ET_KEY_RELEASED); DCHECK_EQ(key_event.type(), ET_KEY_RELEASED);
...@@ -1533,9 +1503,9 @@ void EventRewriterChromeOS::RewriteKeyEventInContext( ...@@ -1533,9 +1503,9 @@ void EventRewriterChromeOS::RewriteKeyEventInContext(
DomKey::Base current_key = key_event.GetDomKey(); DomKey::Base current_key = key_event.GetDomKey();
auto key_state_iter = pressed_key_states_.begin(); auto key_state_iter = pressed_key_states_.begin();
int event_flags = rewritten_event->get() ? (*rewritten_event)->flags() int event_flags =
: key_event.flags(); rewritten_event ? rewritten_event->flags() : key_event.flags();
rewritten_event->reset(); rewritten_event.reset();
// Iterate the keys being pressed. Release the key events which satisfy one // Iterate the keys being pressed. Release the key events which satisfy one
// of the following conditions: // of the following conditions:
...@@ -1548,7 +1518,9 @@ void EventRewriterChromeOS::RewriteKeyEventInContext( ...@@ -1548,7 +1518,9 @@ void EventRewriterChromeOS::RewriteKeyEventInContext(
// code is Launcher should be released because it satisfies the condition 1; // code is Launcher should be released because it satisfies the condition 1;
// the key event whose key code is PageUp should be released because it // the key event whose key code is PageUp should be released because it
// satisfies the condition 2. // satisfies the condition 2.
while (key_state_iter != pressed_key_states_.end()) { ui::EventDispatchDetails details;
while (key_state_iter != pressed_key_states_.end() &&
!details.dispatcher_destroyed) {
const bool is_rewritten = const bool is_rewritten =
(key_state_iter->first.key != key_state_iter->second.key); (key_state_iter->first.key != key_state_iter->second.key);
const bool flag_affected = key_state_iter->second.flags & mapped_flag; const bool flag_affected = key_state_iter->second.flags & mapped_flag;
...@@ -1562,46 +1534,46 @@ void EventRewriterChromeOS::RewriteKeyEventInContext( ...@@ -1562,46 +1534,46 @@ void EventRewriterChromeOS::RewriteKeyEventInContext(
key_event.type(), key_state_iter->first.key_code, key_event.type(), key_state_iter->first.key_code,
key_state_iter->first.code, event_flags, key_state_iter->first.code, event_flags,
key_state_iter->first.key, key_event.time_stamp()); key_state_iter->first.key, key_event.time_stamp());
if (!rewritten_event->get()) details = SendEventFinally(continuation, dispatched_event.get());
*rewritten_event = std::move(dispatched_event);
else
dispatched_key_events_.push_back(std::move(dispatched_event));
key_state_iter = pressed_key_states_.erase(key_state_iter); key_state_iter = pressed_key_states_.erase(key_state_iter);
continue; continue;
} }
key_state_iter++; key_state_iter++;
} }
return details;
}
if (dispatched_key_events_.empty()) { // The released key is not a modifier
*status = rewritten_event->get()
? EventRewriteStatus::EVENT_REWRITE_REWRITTEN current_key_state = MutableKeyState(
: EventRewriteStatus::EVENT_REWRITE_DISCARD; rewritten_event ? static_cast<const ui::KeyEvent*>(rewritten_event.get())
} else { : &key_event);
*status = EventRewriteStatus::EVENT_REWRITE_DISPATCH_ANOTHER; auto iter = std::find_if(pressed_key_states_.begin(),
} pressed_key_states_.end(), key_state_comparator);
} else { if (iter != pressed_key_states_.end()) {
// The released key is not a modifier pressed_key_states_.erase(iter);
current_key_state = MutableKeyState( if (status == EventRewriteStatus::EVENT_REWRITE_CONTINUE)
rewritten_event->get() return SendEvent(continuation, &key_event);
? static_cast<const ui::KeyEvent*>(rewritten_event->get())
: &key_event); ui::EventDispatchDetails details =
auto iter = std::find_if(pressed_key_states_.begin(), SendEventFinally(continuation, rewritten_event.get());
pressed_key_states_.end(), key_state_comparator); if (status == EventRewriteStatus::EVENT_REWRITE_DISPATCH_ANOTHER &&
if (iter != pressed_key_states_.end()) { !details.dispatcher_destroyed) {
pressed_key_states_.erase(iter); return SendStickyKeysReleaseEvents(std::move(rewritten_event),
} else { continuation);
// Event rewriting may create a meaningless key event.
// For example: press the Up Arrow button, press the Launcher button,
// release the Up Arrow. When the Up Arrow button is released, key event
// rewriting happens. However, the rewritten event is not among
// |pressed_key_states_|. So it should be blocked and the original event
// should be propagated.
rewritten_event->reset();
*status = EventRewriteStatus::EVENT_REWRITE_CONTINUE;
} }
return details;
} }
// Event rewriting may create a meaningless key event.
// For example: press the Up Arrow button, press the Launcher button,
// release the Up Arrow. When the Up Arrow button is released, key event
// rewriting happens. However, the rewritten event is not among
// |pressed_key_states_|. So it should be blocked and the original event
// should be propagated.
return SendEvent(continuation, &key_event);
} }
// The keyboard layout for Wilco has a slightly different top-row layout, emits // The keyboard layout for Wilco has a slightly different top-row layout, emits
...@@ -1792,4 +1764,21 @@ EventRewriterChromeOS::DeviceType EventRewriterChromeOS::KeyboardDeviceAdded( ...@@ -1792,4 +1764,21 @@ EventRewriterChromeOS::DeviceType EventRewriterChromeOS::KeyboardDeviceAdded(
return kDeviceUnknown; return kDeviceUnknown;
} }
ui::EventDispatchDetails EventRewriterChromeOS::SendStickyKeysReleaseEvents(
std::unique_ptr<ui::Event> rewritten_event,
const Continuation continuation) {
ui::EventDispatchDetails details;
std::unique_ptr<ui::Event> last_sent_event = std::move(rewritten_event);
while (sticky_keys_controller_ && !details.dispatcher_destroyed) {
std::unique_ptr<ui::Event> new_event;
EventRewriteStatus status = sticky_keys_controller_->NextDispatchEvent(
*last_sent_event, &new_event);
details = SendEventFinally(continuation, new_event.get());
last_sent_event = std::move(new_event);
if (status != EventRewriteStatus::EVENT_REWRITE_DISPATCH_ANOTHER)
return details;
}
return details;
}
} // namespace ui } // namespace ui
...@@ -151,12 +151,6 @@ class EventRewriterChromeOS : public ui::EventRewriter { ...@@ -151,12 +151,6 @@ class EventRewriterChromeOS : public ui::EventRewriter {
ui::EventDispatchDetails RewriteEvent( ui::EventDispatchDetails RewriteEvent(
const ui::Event& event, const ui::Event& event,
const Continuation continuation) override; const Continuation continuation) override;
ui::EventRewriteStatus RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* rewritten_event) override;
ui::EventRewriteStatus NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) override;
// Generate a new key event from an original key event and the replacement // Generate a new key event from an original key event and the replacement
// state determined by a key rewriter. // state determined by a key rewriter.
...@@ -262,9 +256,15 @@ class EventRewriterChromeOS : public ui::EventRewriter { ...@@ -262,9 +256,15 @@ class EventRewriterChromeOS : public ui::EventRewriter {
// Take the keys being pressed into consideration, in contrast to // Take the keys being pressed into consideration, in contrast to
// RewriteKeyEvent which computes the rewritten event and event rewrite // RewriteKeyEvent which computes the rewritten event and event rewrite
// status in stateless way. // status in stateless way.
void RewriteKeyEventInContext(const ui::KeyEvent& event, ui::EventDispatchDetails RewriteKeyEventInContext(
std::unique_ptr<ui::Event>* rewritten_event, const ui::KeyEvent& event,
ui::EventRewriteStatus* status); std::unique_ptr<ui::Event> rewritten_event,
ui::EventRewriteStatus status,
const Continuation continuation);
ui::EventDispatchDetails SendStickyKeysReleaseEvents(
std::unique_ptr<ui::Event> rewritten_event,
const Continuation continuation);
// A set of device IDs whose press event has been rewritten. // A set of device IDs whose press event has been rewritten.
// This is to ensure that press and release events are rewritten consistently. // This is to ensure that press and release events are rewritten consistently.
...@@ -285,9 +285,6 @@ class EventRewriterChromeOS : public ui::EventRewriter { ...@@ -285,9 +285,6 @@ class EventRewriterChromeOS : public ui::EventRewriter {
// element and the second element are identical. // element and the second element are identical.
std::list<std::pair<MutableKeyState, MutableKeyState>> pressed_key_states_; std::list<std::pair<MutableKeyState, MutableKeyState>> pressed_key_states_;
// Store key events when there are more than one key events to be dispatched.
std::vector<std::unique_ptr<ui::KeyEvent>> dispatched_key_events_;
// The sticky keys controller is not owned here; // The sticky keys controller is not owned here;
// at time of writing it is a singleton in ash::Shell. // at time of writing it is a singleton in ash::Shell.
ui::EventRewriter* const sticky_keys_controller_; ui::EventRewriter* const sticky_keys_controller_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment