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

chromeos: converts UIControlsFactoryOzone to use RemoteEventDispatcher

UIControlsFactoryOzone is used to inject events. To make this work
better with the Window Service this patch converts it to use
RemoteEventDispatcher, which routes the event to the Window Service.

BUG=none
TEST=none

Change-Id: Ib7379b3fb6ee4a81cb01145cf24565ad951c8dbe
Reviewed-on: https://chromium-review.googlesource.com/951632
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541278}
parent c4dea4d2
......@@ -277,6 +277,7 @@ jumbo_static_library("test_support") {
"//base/test:test_support",
"//cc:test_support",
"//components/viz/test:test_support",
"//services/service_manager/public/cpp",
"//services/ui/public/cpp/input_devices",
"//services/ui/public/interfaces",
"//skia",
......
......@@ -8,9 +8,14 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/remote_event_dispatcher.mojom.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/test/aura_test_utils.h"
#include "ui/aura/test/env_test_helper.h"
#include "ui/aura/test/ui_controls_factory_aura.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/test/ui_controls_aura.h"
......@@ -21,6 +26,15 @@ namespace aura {
namespace test {
namespace {
// Callback from Window Service with the result of posting an event. |result|
// is true if event successfully processed and |closure| is an optional closure
// to run when done (used in client code to wait for ack).
void OnWindowServiceProcessedEvent(base::OnceClosure closure, bool result) {
DCHECK(result);
if (closure)
std::move(closure).Run();
}
class UIControlsOzone : public ui_controls::UIControlsAura {
public:
UIControlsOzone(WindowTreeHost* host) : host_(host) {}
......@@ -45,48 +59,60 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
if (control) {
flags |= ui::EF_CONTROL_DOWN;
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, flags);
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL, flags,
base::OnceClosure());
}
if (shift) {
flags |= ui::EF_SHIFT_DOWN;
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, flags);
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, flags,
base::OnceClosure());
}
if (alt) {
flags |= ui::EF_ALT_DOWN;
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_MENU, flags);
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_MENU, flags,
base::OnceClosure());
}
if (command) {
flags |= ui::EF_COMMAND_DOWN;
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LWIN, flags);
PostKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LWIN, flags,
base::OnceClosure());
}
PostKeyEvent(ui::ET_KEY_PRESSED, key, flags);
PostKeyEvent(ui::ET_KEY_RELEASED, key, flags);
PostKeyEvent(ui::ET_KEY_PRESSED, key, flags, base::OnceClosure());
const bool has_modifier = control || shift || alt || command;
// Pass the real closure to the last generated KeyEvent.
PostKeyEvent(ui::ET_KEY_RELEASED, key, flags,
has_modifier ? base::OnceClosure() : std::move(closure));
if (alt) {
flags &= ~ui::EF_ALT_DOWN;
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_MENU, flags);
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_MENU, flags,
(shift || control || command) ? base::OnceClosure()
: std::move(closure));
}
if (shift) {
flags &= ~ui::EF_SHIFT_DOWN;
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, flags);
PostKeyEvent(
ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, flags,
(control || command) ? base::OnceClosure() : std::move(closure));
}
if (control) {
flags &= ~ui::EF_CONTROL_DOWN;
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, flags);
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL, flags,
command ? base::OnceClosure() : std::move(closure));
}
if (command) {
flags &= ~ui::EF_COMMAND_DOWN;
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_LWIN, flags);
PostKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_LWIN, flags,
std::move(closure));
}
RunClosureAfterAllPendingUIEvents(std::move(closure));
return true;
}
......@@ -114,9 +140,9 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
else
event_type = ui::ET_MOUSE_MOVED;
PostMouseEvent(event_type, host_location, button_down_mask_, 0);
PostMouseEvent(event_type, host_location, button_down_mask_, 0,
std::move(closure));
RunClosureAfterAllPendingUIEvents(std::move(closure));
return true;
}
bool SendMouseEvents(ui_controls::MouseButton type, int state) override {
......@@ -155,65 +181,91 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
if (state & ui_controls::DOWN) {
button_down_mask_ |= flag;
PostMouseEvent(ui::ET_MOUSE_PRESSED, host_location,
button_down_mask_ | flag, flag);
// Pass the real closure to the last generated MouseEvent.
PostMouseEvent(
ui::ET_MOUSE_PRESSED, host_location, button_down_mask_ | flag, flag,
(state & ui_controls::UP) ? base::OnceClosure() : std::move(closure));
}
if (state & ui_controls::UP) {
button_down_mask_ &= ~flag;
PostMouseEvent(ui::ET_MOUSE_RELEASED, host_location,
button_down_mask_ | flag, flag);
button_down_mask_ | flag, flag, std::move(closure));
}
RunClosureAfterAllPendingUIEvents(std::move(closure));
return true;
}
bool SendMouseClick(ui_controls::MouseButton type) override {
return SendMouseEvents(type, ui_controls::UP | ui_controls::DOWN);
}
void RunClosureAfterAllPendingUIEvents(base::OnceClosure closure) {
if (!closure.is_null())
private:
void SendEventToSink(ui::Event* event, base::OnceClosure closure) {
if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS) {
std::unique_ptr<ui::Event> event_to_send;
if (event->IsMouseEvent()) {
// WindowService expects MouseEvents as PointerEvents.
// See http://crbug.com/617222.
event_to_send =
std::make_unique<ui::PointerEvent>(*event->AsMouseEvent());
} else {
event_to_send = ui::Event::Clone(*event);
}
GetRemoteEventDispatcher()->DispatchEvent(
host_->GetDisplayId(), std::move(event_to_send),
base::BindOnce(&OnWindowServiceProcessedEvent, std::move(closure)));
return;
}
// Post the task before processing the event. This is necessary in case
// processing the event results in a nested message loop.
if (closure) {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(closure));
}
}
private:
void SendEventToSink(ui::Event* event) {
ui::EventSourceTestApi event_source_test(host_->GetEventSource());
ui::EventDispatchDetails details = event_source_test.SendEventToSink(event);
if (details.dispatcher_destroyed)
return;
ignore_result(event_source_test.SendEventToSink(event));
}
void PostKeyEvent(ui::EventType type, ui::KeyboardCode key_code, int flags) {
void PostKeyEvent(ui::EventType type,
ui::KeyboardCode key_code,
int flags,
base::OnceClosure closure) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&UIControlsOzone::PostKeyEventTask,
base::Unretained(this), type, key_code, flags));
FROM_HERE, base::BindOnce(&UIControlsOzone::PostKeyEventTask,
base::Unretained(this), type, key_code, flags,
std::move(closure)));
}
void PostKeyEventTask(ui::EventType type,
ui::KeyboardCode key_code,
int flags) {
int flags,
base::OnceClosure closure) {
// Do not rewrite injected events. See crbug.com/136465.
flags |= ui::EF_FINAL;
ui::KeyEvent key_event(type, key_code, flags);
SendEventToSink(&key_event);
SendEventToSink(&key_event, std::move(closure));
}
void PostMouseEvent(ui::EventType type,
const gfx::Point& host_location,
int flags,
int changed_button_flags) {
int changed_button_flags,
base::OnceClosure closure) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&UIControlsOzone::PostMouseEventTask, base::Unretained(this),
type, host_location, flags, changed_button_flags));
base::BindOnce(&UIControlsOzone::PostMouseEventTask,
base::Unretained(this), type, host_location, flags,
changed_button_flags, std::move(closure)));
}
void PostMouseEventTask(ui::EventType type,
const gfx::Point& host_location,
int flags,
int changed_button_flags) {
int changed_button_flags,
base::OnceClosure closure) {
ui::MouseEvent mouse_event(type, host_location, host_location,
ui::EventTimeForNow(), flags,
changed_button_flags);
......@@ -221,10 +273,25 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
// This hack is necessary to set the repeat count for clicks.
ui::MouseEvent mouse_event2(&mouse_event);
SendEventToSink(&mouse_event2);
SendEventToSink(&mouse_event2, std::move(closure));
}
// Returns the ui::mojom::RemoteEventDispatcher, which is used to send events
// to the Window Service for dispatch.
ui::mojom::RemoteEventDispatcher* GetRemoteEventDispatcher() {
DCHECK_EQ(aura::Env::Mode::MUS, aura::Env::GetInstance()->mode());
if (!remote_event_dispatcher_) {
DCHECK(aura::test::EnvTestHelper().GetWindowTreeClient());
aura::test::EnvTestHelper()
.GetWindowTreeClient()
->connector()
->BindInterface(ui::mojom::kServiceName, &remote_event_dispatcher_);
}
return remote_event_dispatcher_.get();
}
WindowTreeHost* host_;
ui::mojom::RemoteEventDispatcherPtr remote_event_dispatcher_;
// Mask of the mouse buttons currently down. This is static as it needs to
// track the state globally for all displays. A UIControlsOzone instance is
......
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