Commit a5ea6086 authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

reland: chromeos: provide ability to supply event for rewriting

EventRewriters don't honor the target, and so generally expect the
root_location and location to be the same. This patch changes EventSource::SendEventToSink()
to create a new Event if the existing has differing locations (and a target).

BUG=817112
TEST=covered by tests

Change-Id: I29f9cafe962194938c8e457aabc3a5ce6b379649
Reviewed-on: https://chromium-review.googlesource.com/959803Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542809}
parent aacaa90f
......@@ -11,28 +11,14 @@
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/test/test_event_processor.h"
namespace ui {
namespace {
// To test the handling of |EventRewriter|s through |EventSource|,
// we rewrite and test event types.
class TestEvent : public Event {
public:
explicit TestEvent(EventType type)
: Event(type, base::TimeTicks(), 0), unique_id_(next_unique_id_++) {}
~TestEvent() override {}
int unique_id() const { return unique_id_; }
private:
static int next_unique_id_;
int unique_id_;
};
int TestEvent::next_unique_id_ = 0;
// TestEventRewriteProcessor is set up with a sequence of event types,
// and fails if the events received via OnEventFromSource() do not match
// this sequence. These expected event types are consumed on receipt.
......@@ -58,6 +44,28 @@ class TestEventRewriteProcessor : public test::TestEventProcessor {
DISALLOW_COPY_AND_ASSIGN(TestEventRewriteProcessor);
};
std::unique_ptr<Event> CreateEventForType(EventType type) {
switch (type) {
case ET_CANCEL_MODE:
return std::make_unique<CancelModeEvent>();
case ET_MOUSE_DRAGGED:
case ET_MOUSE_PRESSED:
case ET_MOUSE_RELEASED:
return std::make_unique<MouseEvent>(type, gfx::Point(), gfx::Point(),
base::TimeTicks::Now(), 0, 0);
case ET_KEY_PRESSED:
case ET_KEY_RELEASED:
return std::make_unique<KeyEvent>(type, ui::VKEY_TAB, DomCode::NONE, 0);
case ET_SCROLL_FLING_CANCEL:
case ET_SCROLL_FLING_START:
return std::make_unique<ScrollEvent>(
type, gfx::Point(), base::TimeTicks::Now(), 0, 0, 0, 0, 0, 0);
default:
NOTREACHED() << type;
return nullptr;
}
}
// Trivial EventSource that does nothing but send events.
class TestEventRewriteSource : public EventSource {
public:
......@@ -65,7 +73,7 @@ class TestEventRewriteSource : public EventSource {
: processor_(processor) {}
EventProcessor* GetEventSink() override { return processor_; }
void Send(EventType type) {
std::unique_ptr<Event> event(new TestEvent(type));
auto event = CreateEventForType(type);
SendEventToSink(event.get());
}
......@@ -88,7 +96,7 @@ class TestConstantEventRewriter : public EventRewriter {
const Event& event,
std::unique_ptr<Event>* rewritten_event) override {
if (status_ == EVENT_REWRITE_REWRITTEN)
rewritten_event->reset(new TestEvent(type_));
*rewritten_event = CreateEventForType(type_);
return status_;
}
EventRewriteStatus NextDispatchEvent(
......@@ -123,10 +131,10 @@ class TestStateMachineEventRewriter : public EventRewriter {
return EVENT_REWRITE_CONTINUE;
if ((find->second.status == EVENT_REWRITE_REWRITTEN) ||
(find->second.status == EVENT_REWRITE_DISPATCH_ANOTHER)) {
last_rewritten_event_ = new TestEvent(find->second.type);
rewritten_event->reset(last_rewritten_event_);
*rewritten_event = CreateEventForType(find->second.type);
last_rewritten_event_ = rewritten_event->get();
} else {
last_rewritten_event_ = 0;
last_rewritten_event_ = nullptr;
}
state_ = find->second.state;
return find->second.status;
......@@ -135,10 +143,8 @@ class TestStateMachineEventRewriter : public EventRewriter {
const Event& last_event,
std::unique_ptr<Event>* new_event) override {
EXPECT_TRUE(last_rewritten_event_);
const TestEvent* arg_last = static_cast<const TestEvent*>(&last_event);
EXPECT_EQ(last_rewritten_event_->unique_id(), arg_last->unique_id());
const TestEvent* arg_new = static_cast<const TestEvent*>(new_event->get());
EXPECT_FALSE(arg_new && arg_last->unique_id() == arg_new->unique_id());
EXPECT_EQ(last_rewritten_event_, &last_event);
EXPECT_FALSE(new_event->get() && new_event->get() == &last_event);
return RewriteEvent(last_event, new_event);
}
......@@ -151,7 +157,7 @@ class TestStateMachineEventRewriter : public EventRewriter {
};
typedef std::map<RewriteCase, RewriteResult> RewriteRules;
RewriteRules rules_;
TestEvent* last_rewritten_event_;
Event* last_rewritten_event_;
int state_;
};
......
......@@ -11,6 +11,17 @@
#include "ui/events/event_sink.h"
namespace ui {
namespace {
bool IsLocatedEventWithDifferentLocations(const Event& event) {
if (!event.IsLocatedEvent())
return false;
const LocatedEvent* located_event = event.AsLocatedEvent();
return located_event->target() &&
located_event->location_f() != located_event->root_location_f();
}
} // namespace
EventSource::EventSource() {}
......@@ -30,12 +41,23 @@ void EventSource::RemoveEventRewriter(EventRewriter* rewriter) {
}
EventDispatchDetails EventSource::SendEventToSink(Event* event) {
std::unique_ptr<ui::Event> event_for_rewriting_ptr;
Event* event_for_rewriting = event;
if (!rewriter_list_.empty() && IsLocatedEventWithDifferentLocations(*event)) {
// EventRewriters don't expect an event with differing location and
// root-location (because they don't honor the target). Provide such an
// event for rewriters.
event_for_rewriting_ptr = ui::Event::Clone(*event);
event_for_rewriting_ptr->AsLocatedEvent()->set_location_f(
event_for_rewriting_ptr->AsLocatedEvent()->root_location_f());
event_for_rewriting = event_for_rewriting_ptr.get();
}
std::unique_ptr<Event> rewritten_event;
EventRewriteStatus status = EVENT_REWRITE_CONTINUE;
EventRewriterList::const_iterator it = rewriter_list_.begin(),
end = rewriter_list_.end();
for (; it != end; ++it) {
status = (*it)->RewriteEvent(*event, &rewritten_event);
status = (*it)->RewriteEvent(*event_for_rewriting, &rewritten_event);
if (status == EVENT_REWRITE_DISCARD) {
CHECK(!rewritten_event);
return EventDispatchDetails();
......
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