Commit ef8990ce authored by James Cook's avatar James Cook Committed by Commit Bot

cros: Make autoclick work under mash

Generate synthetic clicks and dispatch them via the window service.
Add the remote event dispatcher interface to a new "accessibility"
capability, available only to trusted apps.

Bug: 821471, 628665
Test: Use autoclick on multiple displays with different scale factors
Change-Id: I61352a0849a96a2bc0ae14d0b8afcca051ba67e2
Reviewed-on: https://chromium-review.googlesource.com/961668Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543190}
parent 533531b6
...@@ -28,7 +28,8 @@ class AutoclickControllerCommonDelegate { ...@@ -28,7 +28,8 @@ class AutoclickControllerCommonDelegate {
virtual void UpdateAutoclickRingWidget(views::Widget* widget, virtual void UpdateAutoclickRingWidget(views::Widget* widget,
const gfx::Point& point_in_screen) = 0; const gfx::Point& point_in_screen) = 0;
// Generates a click with |mouse_event_flags| at |point_in_screen|. // Generates a click at |point_in_screen|. |mouse_event_flags| may contain key
// modifiers (e.g. shift, control) for the click.
virtual void DoAutoclick(const gfx::Point& point_in_screen, virtual void DoAutoclick(const gfx::Point& point_in_screen,
const int mouse_event_flags) = 0; const int mouse_event_flags) = 0;
......
...@@ -8,5 +8,7 @@ include_rules = [ ...@@ -8,5 +8,7 @@ include_rules = [
"+services/ui/public", "+services/ui/public",
"+ui/aura/mus", "+ui/aura/mus",
"+ui/base", "+ui/base",
"+ui/display",
"+ui/events",
"+ui/views", "+ui/views",
] ]
...@@ -7,14 +7,20 @@ ...@@ -7,14 +7,20 @@
#include <utility> #include <utility>
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
#include "base/bind_helpers.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_context.h"
#include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/cpp/property_type_converters.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/remote_event_dispatcher.mojom.h"
#include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
#include "ui/aura/mus/property_converter.h" #include "ui/aura/mus/property_converter.h"
#include "ui/base/ui_base_types.h" #include "ui/base/ui_base_types.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/base_event_utils.h"
#include "ui/views/mus/aura_init.h" #include "ui/views/mus/aura_init.h"
#include "ui/views/mus/mus_client.h" #include "ui/views/mus/mus_client.h"
#include "ui/views/mus/pointer_watcher_event_router.h" #include "ui/views/mus/pointer_watcher_event_router.h"
...@@ -166,8 +172,36 @@ void AutoclickApplication::UpdateAutoclickRingWidget( ...@@ -166,8 +172,36 @@ void AutoclickApplication::UpdateAutoclickRingWidget(
void AutoclickApplication::DoAutoclick(const gfx::Point& point_in_screen, void AutoclickApplication::DoAutoclick(const gfx::Point& point_in_screen,
const int mouse_event_flags) { const int mouse_event_flags) {
// TODO(riajiang): Currently not working. Need to know how to generate events // The window service expects display pixel coordinates for events.
// in mus world. https://crbug.com/628665 display::Display display =
display::Screen::GetScreen()->GetDisplayNearestPoint(point_in_screen);
gfx::Point point_in_root(point_in_screen);
point_in_root -= display.bounds().OffsetFromOrigin();
gfx::Point point_in_pixels =
gfx::ScaleToFlooredPoint(point_in_root, display.device_scale_factor());
// Connect to the window service event generation interface.
ui::mojom::RemoteEventDispatcherPtr remote_event_dispatcher;
context()->connector()->BindInterface(ui::mojom::kServiceName,
&remote_event_dispatcher);
// Inject a synthetic click.
ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, point_in_pixels,
point_in_pixels, ui::EventTimeForNow(),
mouse_event_flags | ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, point_in_pixels,
point_in_pixels, ui::EventTimeForNow(),
mouse_event_flags | ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
remote_event_dispatcher->DispatchEvent(
display.id(), std::make_unique<ui::PointerEvent>(press_event),
base::BindOnce([](bool result) { DCHECK(result); }));
// Don't check the next dispatch result because it's possible the first event
// will initiate shutdown.
remote_event_dispatcher->DispatchEvent(
display.id(), std::make_unique<ui::PointerEvent>(release_event),
base::DoNothing());
} }
void AutoclickApplication::OnAutoclickCanceled() { void AutoclickApplication::OnAutoclickCanceled() {
......
...@@ -24,6 +24,9 @@ class Widget; ...@@ -24,6 +24,9 @@ class Widget;
namespace autoclick { namespace autoclick {
// AutoclickApplication is a mojo mini-app that implements the accessibility
// autoclick feature. The feature watches for the mouse to stop moving then
// generates a click after a short delay.
class AutoclickApplication : public service_manager::Service, class AutoclickApplication : public service_manager::Service,
public mash::mojom::Launchable, public mash::mojom::Launchable,
public mojom::AutoclickController, public mojom::AutoclickController,
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
}, },
"requires": { "requires": {
"*": [ "app" ], "*": [ "app" ],
"service_manager": [ "service_manager:service_manager" ] "service_manager": [ "service_manager:service_manager" ],
"ui": [ "privileged" ]
} }
} }
} }
......
...@@ -54,6 +54,10 @@ ...@@ -54,6 +54,10 @@
"input_device_controller": [ "input_device_controller": [
"ui::mojom::InputDeviceController" "ui::mojom::InputDeviceController"
], ],
"privileged": [
// Injecting events is security-sensitive.
"ui::mojom::RemoteEventDispatcher"
],
"window_manager": [ "window_manager": [
"discardable_memory::mojom::DiscardableSharedMemoryManager", "discardable_memory::mojom::DiscardableSharedMemoryManager",
"display::mojom::DisplayController", "display::mojom::DisplayController",
......
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