Commit 883da7ed authored by rkuroiwa's avatar rkuroiwa Committed by Commit bot

Windows Host Touch Injection

- Update SessionInputInjectorWin and InputInjectorWin to
  handle touch events.
- Add TouchInjectorWin which converts TouchEvents to
  structs for Windows touch injection API.

BUG=314515

Review URL: https://codereview.chromium.org/991643002

Cr-Commit-Position: refs/heads/master@{#322116}
parent b4838b40
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "remoting/base/util.h" #include "remoting/base/util.h"
#include "remoting/host/clipboard.h" #include "remoting/host/clipboard.h"
#include "remoting/host/touch_injector_win.h"
#include "remoting/proto/event.pb.h" #include "remoting/proto/event.pb.h"
#include "ui/events/keycodes/dom4/keycode_converter.h" #include "ui/events/keycodes/dom4/keycode_converter.h"
...@@ -87,6 +88,7 @@ class InputInjectorWin : public InputInjector { ...@@ -87,6 +88,7 @@ class InputInjectorWin : public InputInjector {
void InjectKeyEvent(const KeyEvent& event); void InjectKeyEvent(const KeyEvent& event);
void InjectTextEvent(const TextEvent& event); void InjectTextEvent(const TextEvent& event);
void InjectMouseEvent(const MouseEvent& event); void InjectMouseEvent(const MouseEvent& event);
void InjectTouchEvent(const TouchEvent& event);
// Mirrors the InputInjector interface. // Mirrors the InputInjector interface.
void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard); void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard);
...@@ -100,10 +102,12 @@ class InputInjectorWin : public InputInjector { ...@@ -100,10 +102,12 @@ class InputInjectorWin : public InputInjector {
void HandleKey(const KeyEvent& event); void HandleKey(const KeyEvent& event);
void HandleText(const TextEvent& event); void HandleText(const TextEvent& event);
void HandleMouse(const MouseEvent& event); void HandleMouse(const MouseEvent& event);
void HandleTouch(const TouchEvent& event);
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
scoped_ptr<Clipboard> clipboard_; scoped_ptr<Clipboard> clipboard_;
TouchInjectorWin touch_injector_;
DISALLOW_COPY_AND_ASSIGN(Core); DISALLOW_COPY_AND_ASSIGN(Core);
}; };
...@@ -140,7 +144,7 @@ void InputInjectorWin::InjectMouseEvent(const MouseEvent& event) { ...@@ -140,7 +144,7 @@ void InputInjectorWin::InjectMouseEvent(const MouseEvent& event) {
} }
void InputInjectorWin::InjectTouchEvent(const TouchEvent& event) { void InputInjectorWin::InjectTouchEvent(const TouchEvent& event) {
NOTIMPLEMENTED() << "Raw touch event injection not implemented for Windows."; core_->InjectTouchEvent(event);
} }
void InputInjectorWin::Start( void InputInjectorWin::Start(
...@@ -197,6 +201,16 @@ void InputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) { ...@@ -197,6 +201,16 @@ void InputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) {
HandleMouse(event); HandleMouse(event);
} }
void InputInjectorWin::Core::InjectTouchEvent(const TouchEvent& event) {
if (!main_task_runner_->BelongsToCurrentThread()) {
main_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::InjectTouchEvent, this, event));
return;
}
HandleTouch(event);
}
void InputInjectorWin::Core::Start( void InputInjectorWin::Core::Start(
scoped_ptr<protocol::ClipboardStub> client_clipboard) { scoped_ptr<protocol::ClipboardStub> client_clipboard) {
if (!ui_task_runner_->BelongsToCurrentThread()) { if (!ui_task_runner_->BelongsToCurrentThread()) {
...@@ -207,6 +221,7 @@ void InputInjectorWin::Core::Start( ...@@ -207,6 +221,7 @@ void InputInjectorWin::Core::Start(
} }
clipboard_->Start(client_clipboard.Pass()); clipboard_->Start(client_clipboard.Pass());
touch_injector_.Init();
} }
void InputInjectorWin::Core::Stop() { void InputInjectorWin::Core::Stop() {
...@@ -216,6 +231,7 @@ void InputInjectorWin::Core::Stop() { ...@@ -216,6 +231,7 @@ void InputInjectorWin::Core::Stop() {
} }
clipboard_.reset(); clipboard_.reset();
touch_injector_.Deinitialize();
} }
InputInjectorWin::Core::~Core() {} InputInjectorWin::Core::~Core() {}
...@@ -326,6 +342,10 @@ void InputInjectorWin::Core::HandleMouse(const MouseEvent& event) { ...@@ -326,6 +342,10 @@ void InputInjectorWin::Core::HandleMouse(const MouseEvent& event) {
} }
} }
void InputInjectorWin::Core::HandleTouch(const TouchEvent& event) {
touch_injector_.InjectTouchEvent(event);
}
} // namespace } // namespace
scoped_ptr<InputInjector> InputInjector::Create( scoped_ptr<InputInjector> InputInjector::Create(
......
This diff is collapsed.
// Copyright 2015 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 REMOTING_HOST_TOUCH_INJECTOR_WIN_H_
#define REMOTING_HOST_TOUCH_INJECTOR_WIN_H_
#include <windows.h>
#include <map>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/scoped_native_library.h"
namespace remoting {
namespace protocol {
class TouchEvent;
} // namespace protocol
// This class calls InitializeTouchInjection() and InjectTouchInput() functions.
// The methods are virtual for mocking.
class TouchInjectorWinDelegate {
public:
virtual ~TouchInjectorWinDelegate();
// Determines whether Windows touch injection functions can be used.
// Returns a non-null TouchInjectorWinDelegate on success.
static scoped_ptr<TouchInjectorWinDelegate> Create();
// These match the functions in MSDN.
virtual BOOL InitializeTouchInjection(UINT32 max_count, DWORD dw_mode);
virtual DWORD InjectTouchInput(UINT32 count,
const POINTER_TOUCH_INFO* contacts);
protected:
// Ctor in protected scope for mocking.
// This object takes ownership of the |library|.
TouchInjectorWinDelegate(
base::NativeLibrary library,
BOOL(NTAPI* initialize_touch_injection_func)(UINT32, DWORD),
BOOL(NTAPI* inject_touch_input_func)(UINT32, const POINTER_TOUCH_INFO*));
private:
base::ScopedNativeLibrary library_module_;
// Pointers to Windows touch injection functions.
BOOL(NTAPI* initialize_touch_injection_func_)(UINT32, DWORD);
BOOL(NTAPI* inject_touch_input_func_)(UINT32, const POINTER_TOUCH_INFO*);
DISALLOW_COPY_AND_ASSIGN(TouchInjectorWinDelegate);
};
// This class converts TouchEvent objects to POINTER_TOUCH_INFO so that it can
// be injected using the Windows touch injection API, and calls the injection
// functions.
// This class expects good inputs and does not sanity check the inputs.
// This class just converts the object and hands it off to the Windows API.
class TouchInjectorWin {
public:
TouchInjectorWin();
~TouchInjectorWin();
// Returns false if initialization of touch injection APIs fails.
bool Init();
// Deinitializes the object so that it can be reinitialized.
void Deinitialize();
// Inject touch events.
void InjectTouchEvent(const protocol::TouchEvent& event);
void SetInjectorDelegateForTest(
scoped_ptr<TouchInjectorWinDelegate> functions);
private:
// Helper methods called from InjectTouchEvent().
// These helpers adapt Chromoting touch events, which convey changes to touch
// points, to Windows touch descriptions, which must include descriptions for
// all currently-active touch points, not just the changed ones.
void AddNewTouchPoints(const protocol::TouchEvent& event);
void MoveTouchPoints(const protocol::TouchEvent& event);
void EndTouchPoints(const protocol::TouchEvent& event);
void CancelTouchPoints(const protocol::TouchEvent& event);
// Set to null if touch injection is not available from the OS.
scoped_ptr<TouchInjectorWinDelegate> delegate_;
// TODO(rkuroiwa): crbug.com/470203
// This is a naive implementation. Check if we can achieve
// better performance by reducing the number of copies.
// To reduce the number of copies, we can have a vector of
// POINTER_TOUCH_INFO and a map from touch ID to index in the vector.
// When removing points from the vector, just swap it with the last element
// and resize the vector.
// All the POINTER_TOUCH_INFOs are stored as "move" points.
std::map<uint32_t, POINTER_TOUCH_INFO> touches_in_contact_;
DISALLOW_COPY_AND_ASSIGN(TouchInjectorWin);
};
} // namespace remoting
#endif // REMOTING_HOST_TOUCH_INJECTOR_WIN_H_
This diff is collapsed.
...@@ -190,7 +190,14 @@ void SessionInputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) { ...@@ -190,7 +190,14 @@ void SessionInputInjectorWin::Core::InjectMouseEvent(const MouseEvent& event) {
} }
void SessionInputInjectorWin::Core::InjectTouchEvent(const TouchEvent& event) { void SessionInputInjectorWin::Core::InjectTouchEvent(const TouchEvent& event) {
NOTIMPLEMENTED(); if (!input_task_runner_->BelongsToCurrentThread()) {
input_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::InjectTouchEvent, this, event));
return;
}
SwitchToInputDesktop();
nested_executor_->InjectTouchEvent(event);
} }
SessionInputInjectorWin::Core::~Core() { SessionInputInjectorWin::Core::~Core() {
......
...@@ -224,6 +224,8 @@ ...@@ -224,6 +224,8 @@
'host/token_validator_base.h', 'host/token_validator_base.h',
'host/token_validator_factory_impl.cc', 'host/token_validator_factory_impl.cc',
'host/token_validator_factory_impl.h', 'host/token_validator_factory_impl.h',
'host/touch_injector_win.h',
'host/touch_injector_win.cc',
'host/usage_stats_consent.h', 'host/usage_stats_consent.h',
'host/usage_stats_consent_mac.cc', 'host/usage_stats_consent_mac.cc',
'host/usage_stats_consent_win.cc', 'host/usage_stats_consent_win.cc',
......
...@@ -214,6 +214,7 @@ ...@@ -214,6 +214,7 @@
'host/shaped_desktop_capturer_unittest.cc', 'host/shaped_desktop_capturer_unittest.cc',
'host/third_party_auth_config_unittest.cc', 'host/third_party_auth_config_unittest.cc',
'host/token_validator_factory_impl_unittest.cc', 'host/token_validator_factory_impl_unittest.cc',
'host/touch_injector_win_unittest.cc',
'host/video_frame_pump_unittest.cc', 'host/video_frame_pump_unittest.cc',
'host/video_frame_recorder_unittest.cc', 'host/video_frame_recorder_unittest.cc',
'host/win/rdp_client_unittest.cc', 'host/win/rdp_client_unittest.cc',
......
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