Commit 5788540b authored by Jun Mukai's avatar Jun Mukai Committed by Commit Bot

Add SendTouchEvents to ui_controls for ChromeOS

This is used to test asynchronous behaviors of touch in interactive
ui tests for ChromeOS, which also fits with the design of Mash.

See https://docs.google.com/document/d/1h6-dBGUUF2Us4C8ELzqlNyZx1VzcGlenLPDeOBJDJJw/edit?usp=sharing
for the details of the failure reason.

BUG=890071
TEST=tab_drag_controller_intearctive_uitest

Change-Id: I07a292e8f8cd69afa4212f90a52400d612cf6f63
Reviewed-on: https://chromium-review.googlesource.com/c/1309093Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Jun Mukai <mukai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604972}
parent 9a7f768c
......@@ -120,6 +120,21 @@ class UIControlsAsh : public UIControlsAura {
return ui_controls && ui_controls->SendMouseClick(type);
}
bool SendTouchEvents(int action, int id, int x, int y) override {
UIControlsAura* ui_controls = GetUIControlsAt(gfx::Point(x, y));
return ui_controls && ui_controls->SendTouchEvents(action, id, x, y);
}
bool SendTouchEventsNotifyWhenDone(int action,
int id,
int x,
int y,
base::OnceClosure task) override {
UIControlsAura* ui_controls = GetUIControlsAt(gfx::Point(x, y));
return ui_controls && ui_controls->SendTouchEventsNotifyWhenDone(
action, id, x, y, std::move(task));
}
private:
DISALLOW_COPY_AND_ASSIGN(UIControlsAsh);
};
......
......@@ -76,13 +76,11 @@
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/test/event_generator_delegate_aura.h"
#include "ui/aura/test/mus/change_completion_waiter.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/manager/display_manager.h"
#include "ui/events/gesture_detection/gesture_configuration.h"
#include "ui/events/test/event_generator.h"
#endif
#if defined(OS_MACOSX)
......@@ -280,32 +278,6 @@ bool GetIsDragged(Browser* browser) {
} // namespace
#if defined(OS_CHROMEOS)
class ScreenEventGeneratorDelegate
: public aura::test::EventGeneratorDelegateAura {
public:
explicit ScreenEventGeneratorDelegate(aura::Window* root_window)
: root_window_(root_window) {}
~ScreenEventGeneratorDelegate() override {}
// EventGeneratorDelegateAura overrides:
ui::EventTarget* GetTargetAt(const gfx::Point& point) override {
return root_window_->GetHost()->window();
}
aura::client::ScreenPositionClient* GetScreenPositionClient(
const aura::Window* window) const override {
return aura::client::GetScreenPositionClient(root_window_);
}
private:
aura::Window* root_window_;
DISALLOW_COPY_AND_ASSIGN(ScreenEventGeneratorDelegate);
};
#endif
#if !defined(OS_CHROMEOS) && defined(USE_AURA)
// Following classes verify a crash scenario. Specifically on Windows when focus
......@@ -422,7 +394,6 @@ class DetachToBrowserTabDragControllerTest
void SetUpOnMainThread() override {
#if defined(OS_CHROMEOS)
root_ = browser()->window()->GetNativeWindow()->GetRootWindow();
event_generator_ = std::make_unique<ui::test::EventGenerator>(root_);
// Disable flings which might otherwise inadvertently be generated from
// tests' touch events.
ui::GestureConfiguration::GetInstance()->set_min_fling_velocity(
......@@ -442,28 +413,14 @@ class DetachToBrowserTabDragControllerTest
}
#if defined(OS_CHROMEOS)
// Converts the location in screen coordinate's to the location which event
// generator expects (i.e. its root window's coordinate).
gfx::Point GetLocationForEventGenerator(
const gfx::Point& location_in_screen) {
gfx::Point location_in_root = location_in_screen;
aura::client::GetScreenPositionClient(root_)->ConvertPointFromScreen(
root_, &location_in_root);
return location_in_root;
void SendTouchEventsSync(int action, int id, const gfx::Point& location) {
base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
ui_controls::SendTouchEventsNotifyWhenDone(
action, id, location.x(), location.y(), run_loop.QuitClosure());
run_loop.Run();
}
#endif
// Set root window from a point in screen coordinates
void SetEventGeneratorRootWindow(const gfx::Point& point) {
if (input_source() == INPUT_SOURCE_MOUSE)
return;
#if defined(OS_CHROMEOS)
event_generator_ = std::make_unique<ui::test::EventGenerator>(
std::make_unique<ScreenEventGeneratorDelegate>(
ash::wm::GetRootWindowAt(point)));
#endif
}
// The following methods update one of the mouse or touch input depending upon
// the InputSource.
bool PressInput(const gfx::Point& location) {
......@@ -473,9 +430,7 @@ class DetachToBrowserTabDragControllerTest
ui_controls::LEFT, ui_controls::DOWN);
}
#if defined(OS_CHROMEOS)
event_generator_->set_current_location(
GetLocationForEventGenerator(location));
event_generator_->PressTouch();
SendTouchEventsSync(ui_controls::PRESS, 0, location);
#else
NOTREACHED();
#endif
......@@ -486,9 +441,7 @@ class DetachToBrowserTabDragControllerTest
// Second touch input is only used for touch sequence tests.
EXPECT_EQ(INPUT_SOURCE_TOUCH, input_source());
#if defined(OS_CHROMEOS)
event_generator_->set_current_location(
event_generator_->current_location());
event_generator_->PressTouchId(1);
SendTouchEventsSync(ui_controls::PRESS, 1, gfx::Point());
#else
NOTREACHED();
#endif
......@@ -499,7 +452,7 @@ class DetachToBrowserTabDragControllerTest
if (input_source() == INPUT_SOURCE_MOUSE)
return ui_test_utils::SendMouseMoveSync(location);
#if defined(OS_CHROMEOS)
event_generator_->MoveTouch(GetLocationForEventGenerator(location));
SendTouchEventsSync(ui_controls::MOVE, 0, location);
#else
NOTREACHED();
#endif
......@@ -510,7 +463,8 @@ class DetachToBrowserTabDragControllerTest
if (input_source() == INPUT_SOURCE_MOUSE)
return ui_controls::SendMouseMove(location.x(), location.y());
#if defined(OS_CHROMEOS)
event_generator_->MoveTouch(GetLocationForEventGenerator(location));
ui_controls::SendTouchEvents(ui_controls::MOVE, 0, location.x(),
location.y());
#else
NOTREACHED();
#endif
......@@ -521,8 +475,8 @@ class DetachToBrowserTabDragControllerTest
if (input_source() == INPUT_SOURCE_MOUSE)
return ui_controls::SendMouseMoveNotifyWhenDone(x, y, std::move(task));
#if defined(OS_CHROMEOS)
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task));
event_generator_->MoveTouch(GetLocationForEventGenerator(gfx::Point(x, y)));
ui_controls::SendTouchEventsNotifyWhenDone(ui_controls::MOVE, 0, x, y,
std::move(task));
#else
NOTREACHED();
#endif
......@@ -535,9 +489,8 @@ class DetachToBrowserTabDragControllerTest
if (input_source() == INPUT_SOURCE_MOUSE)
return ui_controls::SendMouseMoveNotifyWhenDone(x, y, task);
#if defined(OS_CHROMEOS)
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
event_generator_->MoveTouchId(
GetLocationForEventGenerator(gfx::Point(x, y)), 1);
ui_controls::SendTouchEventsNotifyWhenDone(ui_controls::MOVE, 1, x, y,
std::move(task));
#else
NOTREACHED();
#endif
......@@ -550,7 +503,7 @@ class DetachToBrowserTabDragControllerTest
ui_controls::LEFT, ui_controls::UP);
}
#if defined(OS_CHROMEOS)
event_generator_->ReleaseTouch();
SendTouchEventsSync(ui_controls::RELEASE, 0, gfx::Point());
#else
NOTREACHED();
#endif
......@@ -563,7 +516,7 @@ class DetachToBrowserTabDragControllerTest
ui_controls::LEFT, ui_controls::UP);
}
#if defined(OS_CHROMEOS)
event_generator_->ReleaseTouchId(1);
SendTouchEventsSync(ui_controls::RELEASE, 1, gfx::Point());
#else
NOTREACHED();
#endif
......@@ -598,8 +551,7 @@ class DetachToBrowserTabDragControllerTest
if (input_source() == INPUT_SOURCE_MOUSE)
return ui_test_utils::SendMouseMoveSync(location);
#if defined(OS_CHROMEOS)
event_generator_->set_current_location(
GetLocationForEventGenerator(location));
SendTouchEventsSync(ui_controls::MOVE, 0, location);
#else
NOTREACHED();
#endif
......@@ -666,8 +618,6 @@ class DetachToBrowserTabDragControllerTest
#if defined(OS_CHROMEOS)
// The root window for the event generator.
aura::Window* root_ = nullptr;
std::unique_ptr<ui::test::EventGenerator> event_generator_;
#endif
DISALLOW_COPY_AND_ASSIGN(DetachToBrowserTabDragControllerTest);
......@@ -1147,10 +1097,9 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserTabDragControllerTest,
ASSERT_TRUE(DragInputToNotifyWhenDone(
tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
base::Bind(&DetachToOwnWindowStep2, this)));
if (input_source() == INPUT_SOURCE_MOUSE) {
if (input_source() == INPUT_SOURCE_MOUSE)
ReleaseMouseAfterWindowDetached();
QuitWhenNotDragging();
}
QuitWhenNotDragging();
// Should no longer be dragging.
ASSERT_FALSE(tab_strip->IsDragSessionActive());
......@@ -2126,9 +2075,7 @@ IN_PROC_BROWSER_TEST_P(DetachToBrowserInSeparateDisplayTabDragControllerTest,
// Move to the first tab and drag it enough so that it detaches, but not
// enough that it attaches to browser2.
// SetEventGeneratorRootWindow sets correct (second) RootWindow
gfx::Point tab_0_center(GetCenterInScreenCoordinates(tab_strip->tab_at(0)));
SetEventGeneratorRootWindow(tab_0_center);
ASSERT_TRUE(PressInput(tab_0_center));
ASSERT_TRUE(DragInputToNotifyWhenDone(
tab_0_center.x(), tab_0_center.y() + GetDetachY(tab_strip),
......
......@@ -39,12 +39,7 @@
# TabDragging: crbug.com/890071
-TabDragging/DetachToBrowserInSeparateDisplayTabDragControllerTest.DragBrowserWindowWhenMajorityOfBoundsInSecondDisplay/0
-TabDragging/DetachToBrowserTabDragControllerTest.DeferredTargetTabStripTest/1
-TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindowFromMaximizedWindow/1
-TabDragging/DetachToBrowserTabDragControllerTest.DetachToOwnWindowWhileInImmersiveFullscreenMode/1
-TabDragging/DetachToBrowserTabDragControllerTest.DoNotAttachToOtherWindowTest/1
-TabDragging/DetachToBrowserTabDragControllerTest.DoNotObserveDraggedWidgetAfterDragEnds/1
-TabDragging/DetachToBrowserTabDragControllerTest.DragToOverviewNewWindowItem/1
-TabDragging/DetachToBrowserTabDragControllerTest.DragToOverviewWindow/1
-TabDragging/DetachToBrowserTabDragControllerTest.DragToSeparateWindow/1
-TabDragging/DetachToBrowserTabDragControllerTest.DragWithMaskedWindows/0
......
......@@ -41,6 +41,8 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
public:
UIControlsOzone(WindowTreeHost* host) : host_(host) {}
private:
// ui_controls::UIControlsAura:
bool SendKeyPress(gfx::NativeWindow window,
ui::KeyboardCode key,
bool control,
......@@ -124,18 +126,9 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
bool SendMouseMoveNotifyWhenDone(long screen_x,
long screen_y,
base::OnceClosure closure) override {
// The location needs to be in display's coordinate.
gfx::Point display_location(screen_x, screen_y);
display::Display display;
if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(
host_->GetDisplayId(), &display)) {
LOG(ERROR) << "Failed to see the display for " << host_->GetDisplayId();
gfx::Point host_location(screen_x, screen_y);
if (!ScreenDIPToHostPixels(&host_location))
return false;
}
display_location -= display.bounds().OffsetFromOrigin();
gfx::Point host_location = display_location;
host_->ConvertDIPToPixels(&host_location);
last_mouse_location_ = host_location;
ui::EventType event_type;
......@@ -164,19 +157,9 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
if (last_mouse_location_.has_value()) {
host_location = last_mouse_location_.value();
} else {
// The location needs to be in display's coordinate.
gfx::Point display_location =
host_->window()->env()->last_mouse_location();
display::Display display;
if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(
host_->GetDisplayId(), &display)) {
LOG(ERROR) << "Failed to see the display for " << host_->GetDisplayId();
host_location = host_->window()->env()->last_mouse_location();
if (!ScreenDIPToHostPixels(&host_location))
return false;
}
display_location -= display.bounds().OffsetFromOrigin();
host_location = display_location;
host_->ConvertDIPToPixels(&host_location);
}
int changed_button_flag = 0;
......@@ -228,8 +211,44 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
return SendMouseEvents(type, ui_controls::UP | ui_controls::DOWN,
ui_controls::kNoAccelerator);
}
#if defined(OS_CHROMEOS)
bool SendTouchEvents(int action, int id, int x, int y) override {
return SendTouchEventsNotifyWhenDone(action, id, x, y, base::OnceClosure());
}
bool SendTouchEventsNotifyWhenDone(int action,
int id,
int x,
int y,
base::OnceClosure task) override {
DCHECK_NE(0, action);
gfx::Point host_location(x, y);
if (!ScreenDIPToHostPixels(&host_location))
return false;
bool has_move = action & ui_controls::MOVE;
bool has_release = action & ui_controls::RELEASE;
ui::PointerDetails details(ui::EventPointerType::POINTER_TYPE_TOUCH, id,
1.0f, 1.0f, 0.0f);
if (action & ui_controls::PRESS) {
ui::TouchEvent event(ui::ET_TOUCH_PRESSED, host_location,
base::TimeTicks::Now(), details);
SendEventToSink(&event, (has_move || has_release) ? base::OnceClosure()
: std::move(task));
}
if (has_move) {
ui::TouchEvent event(ui::ET_TOUCH_MOVED, host_location,
base::TimeTicks::Now(), details);
SendEventToSink(&event,
has_release ? base::OnceClosure() : std::move(task));
}
if (has_release) {
ui::TouchEvent event(ui::ET_TOUCH_RELEASED, host_location,
base::TimeTicks::Now(), details);
SendEventToSink(&event, std::move(task));
}
return true;
}
#endif
private:
void SendEventToSink(ui::Event* event, base::OnceClosure closure) {
if (host_->window()->env()->mode() == aura::Env::Mode::MUS) {
GetEventInjector()->InjectEvent(
......@@ -311,6 +330,19 @@ class UIControlsOzone : public ui_controls::UIControlsAura {
return event_injector_.get();
}
bool ScreenDIPToHostPixels(gfx::Point* location) {
// The location needs to be in display's coordinate.
display::Display display;
if (!display::Screen::GetScreen()->GetDisplayWithDisplayId(
host_->GetDisplayId(), &display)) {
LOG(ERROR) << "Failed to find the display for " << host_->GetDisplayId();
return false;
}
*location -= display.bounds().OffsetFromOrigin();
host_->ConvertDIPToPixels(location);
return true;
}
WindowTreeHost* host_;
ws::mojom::EventInjectorPtr event_injector_;
......
......@@ -118,6 +118,17 @@ bool SendMouseClick(MouseButton type);
// pointers, |screen_x| and |screen_y| are the screen coordinates of a touch
// pointer.
bool SendTouchEvents(int action, int num, int screen_x, int screen_y);
#elif defined(OS_CHROMEOS)
// Sends a TouchEvent to the window system. |action| is a bitmask of the
// TouchType constants that indicates what events are generated, |id| identifies
// the touch point.
// TODO(mukai): consolidate this interface with the Windows SendTouchEvents.
bool SendTouchEvents(int action, int id, int x, int y);
bool SendTouchEventsNotifyWhenDone(int action,
int id,
int x,
int y,
base::OnceClosure task);
#endif
#if defined(USE_AURA)
......
......@@ -84,6 +84,23 @@ bool SendTouchEvents(int action, int num, int x, int y) {
CHECK(g_ui_controls_enabled);
return instance_->SendTouchEvents(action, num, x, y);
}
#elif defined(OS_CHROMEOS)
// static
bool SendTouchEvents(int action, int id, int x, int y) {
CHECK(g_ui_controls_enabled);
return instance_->SendTouchEvents(action, id, x, y);
}
// static
bool SendTouchEventsNotifyWhenDone(int action,
int id,
int x,
int y,
base::OnceClosure task) {
CHECK(g_ui_controls_enabled);
return instance_->SendTouchEventsNotifyWhenDone(action, id, x, y,
std::move(task));
}
#endif
UIControlsAura::UIControlsAura() {
......
......@@ -53,6 +53,13 @@ class UIControlsAura {
#if defined(OS_WIN)
virtual bool SendTouchEvents(int action, int num, int x, int y) = 0;
#elif defined(OS_CHROMEOS)
virtual bool SendTouchEvents(int action, int id, int x, int y) = 0;
virtual bool SendTouchEventsNotifyWhenDone(int action,
int id,
int x,
int y,
base::OnceClosure task) = 0;
#endif
};
......
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