Commit 4490a054 authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

aura: adds ability for Env to update shared memory location of mouse

And wires it up for WindowService on top of Aura. Another option is to
add a function to EnvObserver that is called anytime the mouse
location changes, but it didn't seem worth the extra complexity.

BUG=none
TEST=covered by tests

Change-Id: I83c426935b7c618351f5d5a786b8f9c4fc75fd59
Reviewed-on: https://chromium-review.googlesource.com/1024722
Commit-Queue: Scott Violet <sky@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553200}
parent bc45151a
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "services/ui/ws2/window_service_client_binding.h" #include "services/ui/ws2/window_service_client_binding.h"
#include "services/ui/ws2/window_service_delegate.h" #include "services/ui/ws2/window_service_delegate.h"
#include "ui/aura/client/transient_window_client.h" #include "ui/aura/client/transient_window_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
...@@ -932,7 +933,10 @@ void WindowServiceClient::GetWindowManagerClient( ...@@ -932,7 +933,10 @@ void WindowServiceClient::GetWindowManagerClient(
void WindowServiceClient::GetCursorLocationMemory( void WindowServiceClient::GetCursorLocationMemory(
GetCursorLocationMemoryCallback callback) { GetCursorLocationMemoryCallback callback) {
NOTIMPLEMENTED(); auto shared_buffer_handle =
aura::Env::GetInstance()->GetLastMouseLocationMemory();
DCHECK(shared_buffer_handle.is_valid());
std::move(callback).Run(std::move(shared_buffer_handle));
} }
void WindowServiceClient::PerformWindowMove(uint32_t change_id, void WindowServiceClient::PerformWindowMove(uint32_t change_id,
......
...@@ -109,6 +109,8 @@ jumbo_component("aura") { ...@@ -109,6 +109,8 @@ jumbo_component("aura") {
"layout_manager.cc", "layout_manager.cc",
"local/layer_tree_frame_sink_local.cc", "local/layer_tree_frame_sink_local.cc",
"local/window_port_local.cc", "local/window_port_local.cc",
"mouse_location_manager.cc",
"mouse_location_manager.h",
"mus/capture_synchronizer.cc", "mus/capture_synchronizer.cc",
"mus/client_surface_embedder.cc", "mus/client_surface_embedder.cc",
"mus/drag_drop_controller_mus.cc", "mus/drag_drop_controller_mus.cc",
...@@ -363,6 +365,7 @@ test("aura_unittests") { ...@@ -363,6 +365,7 @@ test("aura_unittests") {
"//ui/aura_extra/window_occlusion_impl_unittest_win.cc", "//ui/aura_extra/window_occlusion_impl_unittest_win.cc",
"gestures/gesture_recognizer_unittest.cc", "gestures/gesture_recognizer_unittest.cc",
"hit_test_data_provider_aura_unittest.cc", "hit_test_data_provider_aura_unittest.cc",
"mouse_location_manager_unittest.cc",
"mus/drag_drop_controller_mus_unittest.cc", "mus/drag_drop_controller_mus_unittest.cc",
"mus/focus_synchronizer_unittest.cc", "mus/focus_synchronizer_unittest.cc",
"mus/input_method_mus_unittest.cc", "mus/input_method_mus_unittest.cc",
......
...@@ -8,7 +8,7 @@ include_rules = [ ...@@ -8,7 +8,7 @@ include_rules = [
"+components/viz/common", "+components/viz/common",
"+components/viz/host", "+components/viz/host",
"+mojo/common", "+mojo/common",
"+mojo/public/cpp/bindings", "+mojo/public/cpp",
"+net/base/filename_util.h", "+net/base/filename_util.h",
"+services/service_manager/public/cpp", "+services/service_manager/public/cpp",
"+services/service_manager/public/mojom", "+services/service_manager/public/mojom",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "ui/aura/env_observer.h" #include "ui/aura/env_observer.h"
#include "ui/aura/input_state_lookup.h" #include "ui/aura/input_state_lookup.h"
#include "ui/aura/local/window_port_local.h" #include "ui/aura/local/window_port_local.h"
#include "ui/aura/mouse_location_manager.h"
#include "ui/aura/mus/mus_types.h" #include "ui/aura/mus/mus_types.h"
#include "ui/aura/mus/os_exchange_data_provider_mus.h" #include "ui/aura/mus/os_exchange_data_provider_mus.h"
#include "ui/aura/mus/system_input_injector_mus.h" #include "ui/aura/mus/system_input_injector_mus.h"
...@@ -60,9 +61,10 @@ Env::~Env() { ...@@ -60,9 +61,10 @@ Env::~Env() {
} }
// static // static
std::unique_ptr<Env> Env::CreateInstance(Mode mode) { std::unique_ptr<Env> Env::CreateInstance(Mode mode,
bool create_mouse_location_manager) {
DCHECK(!lazy_tls_ptr.Pointer()->Get()); DCHECK(!lazy_tls_ptr.Pointer()->Get());
std::unique_ptr<Env> env(new Env(mode)); std::unique_ptr<Env> env(new Env(mode, create_mouse_location_manager));
env->Init(); env->Init();
return env; return env;
} }
...@@ -135,6 +137,13 @@ const gfx::Point& Env::last_mouse_location() const { ...@@ -135,6 +137,13 @@ const gfx::Point& Env::last_mouse_location() const {
void Env::SetLastMouseLocation(const gfx::Point& last_mouse_location) { void Env::SetLastMouseLocation(const gfx::Point& last_mouse_location) {
last_mouse_location_ = last_mouse_location; last_mouse_location_ = last_mouse_location;
if (mouse_location_manager_)
mouse_location_manager_->SetMouseLocation(last_mouse_location);
}
mojo::ScopedSharedBufferHandle Env::GetLastMouseLocationMemory() {
DCHECK(mouse_location_manager_);
return mouse_location_manager_->GetMouseLocationMemory();
} }
void Env::SetWindowTreeClient(WindowTreeClient* window_tree_client) { void Env::SetWindowTreeClient(WindowTreeClient* window_tree_client) {
...@@ -158,7 +167,7 @@ void Env::ScheduleEmbed( ...@@ -158,7 +167,7 @@ void Env::ScheduleEmbed(
// static // static
bool Env::initial_throttle_input_on_resize_ = true; bool Env::initial_throttle_input_on_resize_ = true;
Env::Env(Mode mode) Env::Env(Mode mode, bool create_mouse_location_manager)
: mode_(mode), : mode_(mode),
env_controller_(new EnvInputStateController), env_controller_(new EnvInputStateController),
mouse_button_flags_(0), mouse_button_flags_(0),
...@@ -169,6 +178,8 @@ Env::Env(Mode mode) ...@@ -169,6 +178,8 @@ Env::Env(Mode mode)
context_factory_private_(nullptr) { context_factory_private_(nullptr) {
DCHECK(lazy_tls_ptr.Pointer()->Get() == NULL); DCHECK(lazy_tls_ptr.Pointer()->Get() == NULL);
lazy_tls_ptr.Pointer()->Set(this); lazy_tls_ptr.Pointer()->Set(this);
if (create_mouse_location_manager)
mouse_location_manager_ = std::make_unique<MouseLocationManager>();
} }
void Env::Init() { void Env::Init() {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/supports_user_data.h" #include "base/supports_user_data.h"
#include "mojo/public/cpp/system/buffer.h"
#include "ui/aura/aura_export.h" #include "ui/aura/aura_export.h"
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h" #include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
#include "ui/events/event_handler.h" #include "ui/events/event_handler.h"
...@@ -44,6 +45,7 @@ class EnvWindowTreeClientSetter; ...@@ -44,6 +45,7 @@ class EnvWindowTreeClientSetter;
class EnvInputStateController; class EnvInputStateController;
class EnvObserver; class EnvObserver;
class InputStateLookup; class InputStateLookup;
class MouseLocationManager;
class MusMouseLocationUpdater; class MusMouseLocationUpdater;
class Window; class Window;
class WindowPort; class WindowPort;
...@@ -66,9 +68,15 @@ class AURA_EXPORT Env : public ui::EventTarget, ...@@ -66,9 +68,15 @@ class AURA_EXPORT Env : public ui::EventTarget,
~Env() override; ~Env() override;
// Creates a new Env instance. If |create_mouse_location_manager| is true,
// then Env creates a MouseLocationManager that is updated any time the
// mouse location is updated. This is only useful when hosting the
// WindowService on top of Aura (such as Ash).
// NOTE: if you pass in Mode::MUS it is expected that you call // NOTE: if you pass in Mode::MUS it is expected that you call
// SetWindowTreeClient() before any windows are created. // SetWindowTreeClient() before any windows are created.
static std::unique_ptr<Env> CreateInstance(Mode mode = Mode::LOCAL); static std::unique_ptr<Env> CreateInstance(
Mode mode = Mode::LOCAL,
bool create_mouse_location_manager = false);
static Env* GetInstance(); static Env* GetInstance();
static Env* GetInstanceDontCreate(); static Env* GetInstanceDontCreate();
...@@ -97,6 +105,11 @@ class AURA_EXPORT Env : public ui::EventTarget, ...@@ -97,6 +105,11 @@ class AURA_EXPORT Env : public ui::EventTarget,
const gfx::Point& last_mouse_location() const; const gfx::Point& last_mouse_location() const;
void SetLastMouseLocation(const gfx::Point& last_mouse_location); void SetLastMouseLocation(const gfx::Point& last_mouse_location);
// Returns a read-only handle to the shared memory which contains the global
// mouse position. Each call returns a new handle. This is only valid if Env
// was configured to create a MouseLocationManager.
mojo::ScopedSharedBufferHandle GetLastMouseLocationMemory();
// Whether any touch device is currently down. // Whether any touch device is currently down.
bool is_touch_down() const { return is_touch_down_; } bool is_touch_down() const { return is_touch_down_; }
void set_touch_down(bool value) { is_touch_down_ = value; } void set_touch_down(bool value) { is_touch_down_ = value; }
...@@ -144,7 +157,7 @@ class AURA_EXPORT Env : public ui::EventTarget, ...@@ -144,7 +157,7 @@ class AURA_EXPORT Env : public ui::EventTarget,
friend class WindowTreeClient; // For call to WindowTreeClientDestroyed(). friend class WindowTreeClient; // For call to WindowTreeClientDestroyed().
friend class WindowTreeHost; friend class WindowTreeHost;
explicit Env(Mode mode); Env(Mode mode, bool create_mouse_location_manager);
void Init(); void Init();
...@@ -218,6 +231,9 @@ class AURA_EXPORT Env : public ui::EventTarget, ...@@ -218,6 +231,9 @@ class AURA_EXPORT Env : public ui::EventTarget,
static bool initial_throttle_input_on_resize_; static bool initial_throttle_input_on_resize_;
bool throttle_input_on_resize_ = initial_throttle_input_on_resize_; bool throttle_input_on_resize_ = initial_throttle_input_on_resize_;
// Only created if |create_mouse_location_manager| was true.
std::unique_ptr<MouseLocationManager> mouse_location_manager_;
DISALLOW_COPY_AND_ASSIGN(Env); DISALLOW_COPY_AND_ASSIGN(Env);
}; };
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/aura/mouse_location_manager.h"
#include "ui/gfx/geometry/point.h"
namespace aura {
MouseLocationManager::MouseLocationManager() {}
MouseLocationManager::~MouseLocationManager() {}
void MouseLocationManager::SetMouseLocation(const gfx::Point& point_in_dip) {
current_mouse_location_ = static_cast<base::subtle::Atomic32>(
(point_in_dip.x() & 0xFFFF) << 16 | (point_in_dip.y() & 0xFFFF));
if (mouse_location_memory()) {
base::subtle::NoBarrier_Store(mouse_location_memory(),
current_mouse_location_);
}
}
mojo::ScopedSharedBufferHandle MouseLocationManager::GetMouseLocationMemory() {
if (!mouse_location_handle_.is_valid()) {
// Create our shared memory segment to share the mouse state with our
// window clients.
mouse_location_handle_ =
mojo::SharedBufferHandle::Create(sizeof(base::subtle::Atomic32));
if (!mouse_location_handle_.is_valid())
return mojo::ScopedSharedBufferHandle();
mouse_location_mapping_ =
mouse_location_handle_->Map(sizeof(base::subtle::Atomic32));
if (!mouse_location_mapping_)
return mojo::ScopedSharedBufferHandle();
base::subtle::NoBarrier_Store(mouse_location_memory(),
current_mouse_location_);
}
return mouse_location_handle_->Clone(
mojo::SharedBufferHandle::AccessMode::READ_ONLY);
}
} // namespace aura
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_AURA_MOUSE_LOCATION_MANAGER_H_
#define UI_AURA_MOUSE_LOCATION_MANAGER_H_
#include "base/atomicops.h"
#include "base/macros.h"
#include "mojo/public/cpp/system/buffer.h"
namespace gfx {
class Point;
}
namespace aura {
// Manages a shared memory buffer that stores the mouse location. It is
// expected Env calls SetMouseLocation() any time the location of the mouse
// changes.
class MouseLocationManager {
public:
MouseLocationManager();
~MouseLocationManager();
// Sets the current mouse location to |point|. Atomically writes the location
// to shared memory. |point| should be in screen-coord and DIP.
void SetMouseLocation(const gfx::Point& point_in_dip);
// Returns a read-only handle to the shared memory which contains the global
// mouse position. Each call returns a new handle.
mojo::ScopedSharedBufferHandle GetMouseLocationMemory();
private:
base::subtle::Atomic32* mouse_location_memory() {
return reinterpret_cast<base::subtle::Atomic32*>(
mouse_location_mapping_.get());
}
// The current location of the mouse. This is always kept up to date so we
// can atomically write this to |mouse_location_memory()| once it is created.
base::subtle::Atomic32 current_mouse_location_ = 0;
// A handle to a shared memory buffer that is one 32 bit integer long. We
// share this with any client as the same user. This buffer is lazily
// created on the first access.
mojo::ScopedSharedBufferHandle mouse_location_handle_;
// The one int32 in |mouse_location_handle_|. When we write to this
// location, we must always write to it atomically. (On the other side of the
// mojo connection, this data must be read atomically.)
mojo::ScopedSharedBufferMapping mouse_location_mapping_;
DISALLOW_COPY_AND_ASSIGN(MouseLocationManager);
};
} // namespace aura
#endif // UI_AURA_MOUSE_LOCATION_MANAGER_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/atomicops.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/env.h"
#include "ui/aura/test/aura_test_suite.h"
#include "ui/gfx/geometry/point.h"
namespace aura {
namespace {
gfx::Point Atomic32ToPoint(base::subtle::Atomic32 atomic) {
return gfx::Point(static_cast<int16_t>(atomic >> 16),
static_cast<int16_t>(atomic & 0xFFFF));
}
} // namespace
TEST(MouseLocationManagerTest, PositiveCoordinates) {
test::EnvReinstaller reinstaller;
const bool create_mouse_location_manager = true;
auto env =
Env::CreateInstance(Env::Mode::LOCAL, create_mouse_location_manager);
const gfx::Point point(100, 150);
env->SetLastMouseLocation(point);
base::subtle::Atomic32* cursor_location_memory = nullptr;
mojo::ScopedSharedBufferHandle handle = env->GetLastMouseLocationMemory();
ASSERT_TRUE(handle.is_valid());
mojo::ScopedSharedBufferMapping cursor_location_mapping =
handle->Map(sizeof(base::subtle::Atomic32));
ASSERT_TRUE(cursor_location_mapping);
cursor_location_memory =
reinterpret_cast<base::subtle::Atomic32*>(cursor_location_mapping.get());
base::subtle::Atomic32 location =
base::subtle::NoBarrier_Load(cursor_location_memory);
EXPECT_EQ(point, Atomic32ToPoint(location));
}
TEST(MouseLocationManagerTest, NegativeCoordinates) {
test::EnvReinstaller reinstaller;
const bool create_mouse_location_manager = true;
auto env =
Env::CreateInstance(Env::Mode::LOCAL, create_mouse_location_manager);
const gfx::Point point(-10, -11);
env->SetLastMouseLocation(point);
base::subtle::Atomic32* cursor_location_memory = nullptr;
mojo::ScopedSharedBufferHandle handle = env->GetLastMouseLocationMemory();
ASSERT_TRUE(handle.is_valid());
mojo::ScopedSharedBufferMapping cursor_location_mapping =
handle->Map(sizeof(base::subtle::Atomic32));
ASSERT_TRUE(cursor_location_mapping);
cursor_location_memory =
reinterpret_cast<base::subtle::Atomic32*>(cursor_location_mapping.get());
base::subtle::Atomic32 location =
base::subtle::NoBarrier_Load(cursor_location_memory);
EXPECT_EQ(point, Atomic32ToPoint(location));
}
} // namespace aura
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