summaryrefslogtreecommitdiffstats
path: root/remoting/client
diff options
context:
space:
mode:
authornkostylev@chromium.org <nkostylev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-13 07:15:53 +0000
committernkostylev@chromium.org <nkostylev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-13 07:15:53 +0000
commitad907cab8a57d73110eec0b75c8e8376497d39a2 (patch)
tree38180260d892beb11c37d009b94c5c5d9921b793 /remoting/client
parent1ed51f572f13b695021ac8c187a30b91ae33fb95 (diff)
downloadchromium_src-ad907cab8a57d73110eec0b75c8e8376497d39a2.zip
chromium_src-ad907cab8a57d73110eec0b75c8e8376497d39a2.tar.gz
chromium_src-ad907cab8a57d73110eec0b75c8e8376497d39a2.tar.bz2
Revert 217207 "Work around OSKey being used as a rewriting modif..."
> Work around OSKey being used as a rewriting modifier to get extended keys on CrOS. > > Moves MacKeyEventProcessor to NormalizingInputFilterMac and adds a NormalizingInputFilterAsh which tries to properly distinguish the key-writing versus key-modifying behaviours of OSKey (CrOS' Search key). > > BUG=230049 > > Review URL: https://chromiumcodereview.appspot.com/18345018 TBR=wez@chromium.org Review URL: https://codereview.chromium.org/22897003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217223 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client')
-rw-r--r--remoting/client/plugin/chromoting_instance.cc10
-rw-r--r--remoting/client/plugin/chromoting_instance.h6
-rw-r--r--remoting/client/plugin/mac_key_event_processor.cc (renamed from remoting/client/plugin/normalizing_input_filter_mac.cc)79
-rw-r--r--remoting/client/plugin/mac_key_event_processor.h76
-rw-r--r--remoting/client/plugin/mac_key_event_processor_unittest.cc (renamed from remoting/client/plugin/normalizing_input_filter_mac_unittest.cc)92
-rw-r--r--remoting/client/plugin/normalizing_input_filter.cc20
-rw-r--r--remoting/client/plugin/normalizing_input_filter.h21
-rw-r--r--remoting/client/plugin/normalizing_input_filter_ash.cc206
-rw-r--r--remoting/client/plugin/normalizing_input_filter_ash_unittest.cc212
9 files changed, 140 insertions, 582 deletions
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 3469ca2..e22452a 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -174,9 +174,15 @@ ChromotingInstance::ChromotingInstance(PP_Instance pp_instance)
plugin_task_runner_(new PluginThreadTaskRunner(&plugin_thread_delegate_)),
context_(plugin_task_runner_.get()),
input_tracker_(&mouse_input_filter_),
+#if defined(OS_MACOSX)
+ // On Mac we need an extra filter to inject missing keyup events.
+ // See remoting/client/plugin/mac_key_event_processor.h for more details.
+ mac_key_event_processor_(&input_tracker_),
+ key_mapper_(&mac_key_event_processor_),
+#else
key_mapper_(&input_tracker_),
- normalizing_input_filter_(CreateNormalizingInputFilter(&key_mapper_)),
- input_handler_(normalizing_input_filter_.get()),
+#endif
+ input_handler_(&key_mapper_),
use_async_pin_dialog_(false),
weak_factory_(this) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL);
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 4c786e1..23c4c49 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -31,7 +31,7 @@
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
#include "remoting/client/key_event_mapper.h"
-#include "remoting/client/plugin/normalizing_input_filter.h"
+#include "remoting/client/plugin/mac_key_event_processor.h"
#include "remoting/client/plugin/pepper_input_handler.h"
#include "remoting/client/plugin/pepper_plugin_thread_delegate.h"
#include "remoting/proto/event.pb.h"
@@ -248,8 +248,10 @@ class ChromotingInstance :
// Input pipeline components, in reverse order of distance from input source.
protocol::MouseInputFilter mouse_input_filter_;
protocol::InputEventTracker input_tracker_;
+#if defined(OS_MACOSX)
+ MacKeyEventProcessor mac_key_event_processor_;
+#endif
KeyEventMapper key_mapper_;
- scoped_ptr<protocol::InputFilter> normalizing_input_filter_;
PepperInputHandler input_handler_;
// PIN Fetcher.
diff --git a/remoting/client/plugin/normalizing_input_filter_mac.cc b/remoting/client/plugin/mac_key_event_processor.cc
index 56b327e..175924bf 100644
--- a/remoting/client/plugin/normalizing_input_filter_mac.cc
+++ b/remoting/client/plugin/mac_key_event_processor.cc
@@ -1,49 +1,12 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
-// NormalizingInputFilterMac is designed to solve the problem of missing keyup
-// events on Mac.
-//
-// PROBLEM
-//
-// On Mac if user presses CMD and then C key there is no keyup event generated
-// for C when user releases the C key before the CMD key.
-// The cause is that CMD + C triggers a system action and Chrome injects only a
-// keydown event for the C key. Safari shares the same behavior.
-//
-// SOLUTION
-//
-// When a keyup event for CMD key happens we will check all prior keydown
-// events received and inject corresponding keyup events artificially, with
-// the exception of:
-//
-// SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK
-//
-// because they are reported by Chrome correctly.
-//
-// There are a couple cases that this solution doesn't work perfectly, one
-// of them leads to duplicated keyup events.
-//
-// User performs this sequence of actions:
-//
-// CMD DOWN, C DOWN, CMD UP, C UP
-//
-// In this case the algorithm will generate:
-//
-// CMD DOWN, C DOWN, C UP, CMD UP, C UP
-//
-// Because we artificially generate keyup events the C UP event is duplicated
-// as user releases the key after CMD key. This would not be a problem as the
-// receiver end will drop this duplicated keyup event.
-
-#include "remoting/client/plugin/normalizing_input_filter.h"
-
-#include <map>
+#include "remoting/client/plugin/mac_key_event_processor.h"
+
#include <vector>
#include "base/logging.h"
-#include "remoting/proto/event.pb.h"
namespace remoting {
@@ -62,32 +25,14 @@ const unsigned int kUsbTab = 0x07002b;
} // namespace
-class NormalizingInputFilterMac : public protocol::InputFilter {
- public:
- explicit NormalizingInputFilterMac(protocol::InputStub* input_stub);
- virtual ~NormalizingInputFilterMac() {}
-
- // InputFilter overrides.
- virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE;
-
- private:
- // Generate keyup events for any keys pressed with CMD.
- void GenerateKeyupEvents();
-
- // A map that stores pressed keycodes and the corresponding key event.
- typedef std::map<int, protocol::KeyEvent> KeyPressedMap;
- KeyPressedMap key_pressed_map_;
-
- DISALLOW_COPY_AND_ASSIGN(NormalizingInputFilterMac);
-};
-
-NormalizingInputFilterMac::NormalizingInputFilterMac(
- protocol::InputStub* input_stub)
+MacKeyEventProcessor::MacKeyEventProcessor(protocol::InputStub* input_stub)
: protocol::InputFilter(input_stub) {
}
-void NormalizingInputFilterMac::InjectKeyEvent(const protocol::KeyEvent& event)
-{
+MacKeyEventProcessor::~MacKeyEventProcessor() {
+}
+
+void MacKeyEventProcessor::InjectKeyEvent(const protocol::KeyEvent& event) {
DCHECK(event.has_usb_keycode());
bool is_special_key = event.usb_keycode() == kUsbLeftControl ||
@@ -131,7 +76,7 @@ void NormalizingInputFilterMac::InjectKeyEvent(const protocol::KeyEvent& event)
InputFilter::InjectKeyEvent(event);
}
-void NormalizingInputFilterMac::GenerateKeyupEvents() {
+void MacKeyEventProcessor::GenerateKeyupEvents() {
for (KeyPressedMap::iterator i = key_pressed_map_.begin();
i != key_pressed_map_.end(); ++i) {
// The generated key up event will have the same key code and lock states
@@ -145,10 +90,4 @@ void NormalizingInputFilterMac::GenerateKeyupEvents() {
key_pressed_map_.clear();
}
-scoped_ptr<protocol::InputFilter> CreateNormalizingInputFilter(
- protocol::InputStub* input_stub) {
- return scoped_ptr<protocol::InputFilter>(
- new NormalizingInputFilterMac(input_stub));
-}
-
} // namespace remoting
diff --git a/remoting/client/plugin/mac_key_event_processor.h b/remoting/client/plugin/mac_key_event_processor.h
new file mode 100644
index 0000000..56bc974
--- /dev/null
+++ b/remoting/client/plugin/mac_key_event_processor.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 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.
+
+// MacKeyEventProcessor is designed to solve the problem of missing keyup
+// events on Mac.
+//
+// PROBLEM
+//
+// On Mac if user presses CMD and then C key there is no keyup event generated
+// for C when user releases the C key before the CMD key.
+// The cause is that CMD + C triggers a system action and Chrome injects only a
+// keydown event for the C key. Safari shares the same behavior.
+//
+// SOLUTION
+//
+// When a keyup event for CMD key happens we will check all prior keydown
+// events received and inject corresponding keyup events artificially, with
+// the exception of:
+//
+// SHIFT, CONTROL, OPTION, LEFT CMD, RIGHT CMD and CAPS LOCK
+//
+// because they are reported by Chrome correctly.
+//
+// There are a couple cases that this solution doesn't work perfectly, one
+// of them leads to duplicated keyup events.
+//
+// User performs this sequence of actions:
+//
+// CMD DOWN, C DOWN, CMD UP, C UP
+//
+// In this case the algorithm will generate:
+//
+// CMD DOWN, C DOWN, C UP, CMD UP, C UP
+//
+// Because we artificially generate keyup events the C UP event is duplicated
+// as user releases the key after CMD key. This would not be a problem as the
+// receiver end will drop this duplicated keyup event.
+
+#ifndef REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_
+#define REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "remoting/proto/event.pb.h"
+#include "remoting/protocol/input_filter.h"
+
+namespace remoting {
+
+namespace protocol {
+class InputStub;
+} // namespace protocol
+
+class MacKeyEventProcessor : public protocol::InputFilter {
+ public:
+ explicit MacKeyEventProcessor(protocol::InputStub* input_stub);
+ virtual ~MacKeyEventProcessor();
+
+ // InputFilter overrides.
+ virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE;
+
+ private:
+ // Generate keyup events for any keys pressed with CMD.
+ void GenerateKeyupEvents();
+
+ // A map that stores pressed keycodes and the corresponding key event.
+ typedef std::map<int, protocol::KeyEvent> KeyPressedMap;
+ KeyPressedMap key_pressed_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(MacKeyEventProcessor);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_CLIENT_PLUGIN_MAC_KEY_EVENT_PROCESSOR_H_
diff --git a/remoting/client/plugin/normalizing_input_filter_mac_unittest.cc b/remoting/client/plugin/mac_key_event_processor_unittest.cc
index 8221223..a2604d5 100644
--- a/remoting/client/plugin/normalizing_input_filter_mac_unittest.cc
+++ b/remoting/client/plugin/mac_key_event_processor_unittest.cc
@@ -1,8 +1,8 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 "remoting/client/plugin/normalizing_input_filter.h"
+#include "remoting/client/plugin/mac_key_event_processor.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/protocol_mock_objects.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -44,10 +44,9 @@ KeyEvent MakeKeyEvent(uint32 keycode, bool pressed) {
} // namespace
// Test CapsLock press/release.
-TEST(NormalizingInputFilterMacTest, CapsLock) {
+TEST(MacKeyEventProcessorTest, CapsLock) {
MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
+ MacKeyEventProcessor processor(&stub);
{
InSequence s;
@@ -58,14 +57,13 @@ TEST(NormalizingInputFilterMacTest, CapsLock) {
}
// Injecting a CapsLock down event with NumLock on.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbCapsLock, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbCapsLock, true));
}
// Test without pressing command key.
-TEST(NormalizingInputFilterMacTest, NoInjection) {
+TEST(MacKeyEventProcessorTest, NoInjection) {
MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
+ MacKeyEventProcessor processor(&stub);
{
InSequence s;
@@ -77,15 +75,14 @@ TEST(NormalizingInputFilterMacTest, NoInjection) {
}
// C Down and C Up.
- processor->InjectKeyEvent(MakeKeyEvent('C', true));
- processor->InjectKeyEvent(MakeKeyEvent('C', false));
+ processor.InjectKeyEvent(MakeKeyEvent('C', true));
+ processor.InjectKeyEvent(MakeKeyEvent('C', false));
}
// Test pressing command key and other normal keys.
-TEST(NormalizingInputFilterMacTest, CmdKey) {
+TEST(MacKeyEventProcessorTest, CmdKey) {
MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
+ MacKeyEventProcessor processor(&stub);
{
InSequence s;
@@ -126,27 +123,26 @@ TEST(NormalizingInputFilterMacTest, CmdKey) {
}
// Left command key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent('C', true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent('C', true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
// Right command key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent('C', true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent('C', true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, false));
// More than one keys after CMD.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent('C', true));
- processor->InjectKeyEvent(MakeKeyEvent('V', true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent('C', true));
+ processor.InjectKeyEvent(MakeKeyEvent('V', true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, false));
}
// Test pressing command and special keys.
-TEST(NormalizingInputFilterMacTest, SpecialKeys) {
+TEST(MacKeyEventProcessorTest, SpecialKeys) {
MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
+ MacKeyEventProcessor processor(&stub);
{
InSequence s;
@@ -173,23 +169,22 @@ TEST(NormalizingInputFilterMacTest, SpecialKeys) {
}
// Command + Shift.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftShift, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftShift, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftShift, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftShift, false));
// Command + Option.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOption, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOption, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftOption, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftOption, false));
}
// Test pressing multiple command keys.
-TEST(NormalizingInputFilterMacTest, MultipleCmdKeys) {
+TEST(MacKeyEventProcessorTest, MultipleCmdKeys) {
MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
+ MacKeyEventProcessor processor(&stub);
{
InSequence s;
@@ -208,17 +203,16 @@ TEST(NormalizingInputFilterMacTest, MultipleCmdKeys) {
// Test multiple CMD keys at the same time.
// L CMD Down, C Down, R CMD Down, L CMD Up.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent('C', true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent('C', true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbLeftCmd, false));
}
// Test press C key before command key.
-TEST(NormalizingInputFilterMacTest, BeforeCmdKey) {
+TEST(MacKeyEventProcessorTest, BeforeCmdKey) {
MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
+ MacKeyEventProcessor processor(&stub);
{
InSequence s;
@@ -236,10 +230,10 @@ TEST(NormalizingInputFilterMacTest, BeforeCmdKey) {
}
// Press C before command key.
- processor->InjectKeyEvent(MakeKeyEvent('C', true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, false));
- processor->InjectKeyEvent(MakeKeyEvent('C', false));
+ processor.InjectKeyEvent(MakeKeyEvent('C', true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, true));
+ processor.InjectKeyEvent(MakeKeyEvent(kUsbRightCmd, false));
+ processor.InjectKeyEvent(MakeKeyEvent('C', false));
}
} // namespace remoting
diff --git a/remoting/client/plugin/normalizing_input_filter.cc b/remoting/client/plugin/normalizing_input_filter.cc
deleted file mode 100644
index 7206305..0000000
--- a/remoting/client/plugin/normalizing_input_filter.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2013 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 "remoting/client/plugin/normalizing_input_filter.h"
-
-#include "remoting/protocol/input_filter.h"
-
-namespace remoting {
-
-using protocol::InputFilter;
-using protocol::InputStub;
-
-#if !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
-scoped_ptr<InputFilter> CreateNormalizingInputFilter(InputStub* input_stub) {
- return scoped_ptr<InputFilter>(new InputFilter(input_stub));
-}
-#endif // !defined(OS_MACOSX) && !defined(OS_CHROMEOS)
-
-}
diff --git a/remoting/client/plugin/normalizing_input_filter.h b/remoting/client/plugin/normalizing_input_filter.h
deleted file mode 100644
index ebe49fe..0000000
--- a/remoting/client/plugin/normalizing_input_filter.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013 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_CLIENT_PLUGIN_NORMALIZING_INPUT_FILTER_H_
-#define REMOTING_CLIENT_PLUGIN_NORMALIZING_INPUT_FILTER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "remoting/protocol/input_filter.h"
-
-namespace remoting {
-
-// Returns an InputFilter which re-writes input events to work around
-// platform-specific behaviours. If no re-writing is required then a
-// pass-through InputFilter is returned.
-scoped_ptr<protocol::InputFilter> CreateNormalizingInputFilter(
- protocol::InputStub* input_stub);
-
-} // namespace remoting
-
-#endif // REMOTING_CLIENT_PLUGIN_NORMALIZING_INPUT_FILTER_H_
diff --git a/remoting/client/plugin/normalizing_input_filter_ash.cc b/remoting/client/plugin/normalizing_input_filter_ash.cc
deleted file mode 100644
index 113d955..0000000
--- a/remoting/client/plugin/normalizing_input_filter_ash.cc
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2013 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.
-
-// NormalizingInputFilterAsh addresses the problems generated by key rewritings
-// such as Down->PageDown, 1->F1, etc, when keys are pressed in combination with
-// the OSKey (aka Search). Rewriting OSKey+Down, for example, causes us to
-// receive the following:
-//
-// keydown OSKey
-// keydown PageDown
-// keyup PageDown
-// keyup OSKey
-//
-// The host system will therefore behave as if OSKey+PageDown were pressed,
-// rather than PageDown alone.
-//
-// This file must be kept up-to-date with changes to
-// chrome/browser/ui/ash/event_rewriter.cc
-
-#include "remoting/client/plugin/normalizing_input_filter.h"
-
-#include "base/logging.h"
-#include "remoting/proto/event.pb.h"
-
-namespace remoting {
-
-namespace {
-
-// Returns true for OSKey codes.
-static bool IsOsKey(unsigned int code) {
- const unsigned int kUsbLeftOsKey = 0x0700e3;
- const unsigned int kUsbRightOsKey = 0x0700e7;
- return code == kUsbLeftOsKey || code == kUsbRightOsKey;
-}
-
-// Returns true for codes generated by EventRewriter::RewriteFunctionKeys().
-static bool IsRewrittenFunctionKey(unsigned int code) {
- const unsigned int kUsbFunctionKeyMin = 0x07003a;
- const unsigned int kUsbFunctionKeyMax = 0x070045;
- return code >= kUsbFunctionKeyMin && code <= kUsbFunctionKeyMax;
-}
-
-// Returns true for codes generated by EventRewriter::RewriteExtendedKeys().
-static bool IsRewrittenExtendedKey(unsigned int code) {
- const unsigned int kUsbExtendedKeyMin = 0x070049;
- const unsigned int kUsbExtendedKeyMax = 0x07004e;
- return code >= kUsbExtendedKeyMin && code <= kUsbExtendedKeyMax;
-}
-
-// Returns true for codes generated by EventRewriter::Rewrite().
-static bool IsRewrittenKey(unsigned int code) {
- return IsRewrittenExtendedKey(code) || IsRewrittenFunctionKey(code);
-}
-
-// The input filter tries to avoid sending keydown/keyup events for OSKey
-// (aka Search, WinKey, Cmd, Super) when it is used to rewrite other key events.
-// Rewriting via other combinations is not currently handled.
-//
-// OSKey events can be categorised as one of three kinds:
-// - Modifying - Holding the key down while executing other input modifies the
-// effect of that input, e.g. OSKey+L causes the workstation to lock, e.g.
-// OSKey + mouse-move performs an extended selection.
-// - Rewriting (ChromeOS only) - Holding the key down while pressing certain
-// keys causes them to be treated as different keys, e.g. OSKey causes the
-// Down key to behave as PageDown.
-// - Normal - Press & release of the key trigger an action, e.g. showing the
-// Start menu.
-//
-// The input filter has four states:
-// 1. No OSKey has been pressed.
-// - When an OSKey keydown is received, the event is deferred, and we move to
-// State #2.
-// 2. An OSKey is pressed, but may be Normal, Rewriting or Modifying.
-// - If the OSKey keyup is received, the key is Normal, both events are sent
-// and we return to State #1.
-// - If a Rewritten event is received we move to State #3.
-// - If a Modified event is received the OSKey keydown is sent and we enter
-// State #4.
-// 3. An OSKey is pressed, and is being used to Rewrite other key events.
-// - If the OSKey keyup is received then it is suppressed, and we move to
-// State #1.
-// - If a Modified event is received the OSKey keydown is sent and we enter
-// State #4.
-// - If a Rewritten event is received then we stay in State #3.
-// 4. An OSKey is pressed, and is Modifying.
-// - If the OSKey keyup is received then we send it and we move to State #1.
-// - All other key event pass through the filter unchanged.
-
-class NormalizingInputFilterAsh : public protocol::InputFilter {
- public:
- explicit NormalizingInputFilterAsh(protocol::InputStub* input_stub)
- : protocol::InputFilter(input_stub),
- deferred_key_is_rewriting_(false),
- modifying_key_(0) {
- }
- virtual ~NormalizingInputFilterAsh() {}
-
- // InputFilter overrides.
- virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE {
- DCHECK(event.has_usb_keycode());
- DCHECK(event.has_pressed());
-
- if (event.pressed())
- ProcessKeyDown(event);
- else
- ProcessKeyUp(event);
- }
-
- virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE {
- if (deferred_keydown_event_.has_usb_keycode())
- SwitchRewritingKeyToModifying();
- InputFilter::InjectMouseEvent(event);
- }
-
- private:
- void ProcessKeyDown(const protocol::KeyEvent& event) {
- // If |event| is |deferred_keydown_event_| auto-repeat then assume
- // that the user is holding the key down rather than using it to Rewrite.
- if (deferred_keydown_event_.has_usb_keycode() &&
- deferred_keydown_event_.usb_keycode() == event.usb_keycode()) {
- SwitchRewritingKeyToModifying();
- }
-
- // If |event| is a |modifying_key_| repeat then let it pass through.
- if (modifying_key_ == event.usb_keycode()) {
- InputFilter::InjectKeyEvent(event);
- return;
- }
-
- // If |event| is for an OSKey and we don't know whether it's a Normal,
- // Rewriting or Modifying use, then hold the keydown event.
- if (IsOsKey(event.usb_keycode())) {
- deferred_keydown_event_ = event;
- deferred_key_is_rewriting_ = false;
- return;
- }
-
- // If |event| is for a Rewritten key then set a flag to prevent any deferred
- // OSKey keydown from being sent when keyup is received for it. Otherwise,
- // inject the deferred OSKey keydown, if any, and switch that key into
- // Modifying mode.
- if (IsRewrittenKey(event.usb_keycode())) {
- // Note that there may not be a deferred OSKey event if there is a full
- // PC keyboard connected, which can generate e.g. PageDown without
- // rewriting.
- deferred_key_is_rewriting_ = true;
- } else {
- if (deferred_keydown_event_.has_usb_keycode())
- SwitchRewritingKeyToModifying();
- }
-
- InputFilter::InjectKeyEvent(event);
- }
-
- void ProcessKeyUp(const protocol::KeyEvent& event) {
- if (deferred_keydown_event_.has_usb_keycode() &&
- deferred_keydown_event_.usb_keycode() == event.usb_keycode()) {
- if (deferred_key_is_rewriting_) {
- // If we never sent the keydown then don't send a keyup.
- deferred_keydown_event_ = protocol::KeyEvent();
- return;
- }
-
- // If the OSKey hasn't Rewritten anything then treat as Modifying.
- SwitchRewritingKeyToModifying();
- }
-
- if (modifying_key_ == event.usb_keycode())
- modifying_key_ = 0;
-
- InputFilter::InjectKeyEvent(event);
- }
-
- void SwitchRewritingKeyToModifying() {
- DCHECK(deferred_keydown_event_.has_usb_keycode());
- modifying_key_ = deferred_keydown_event_.usb_keycode();
- InputFilter::InjectKeyEvent(deferred_keydown_event_);
- deferred_keydown_event_ = protocol::KeyEvent();
- }
-
- // Holds the keydown event for the most recent OSKey to have been pressed,
- // while it is Rewriting, or we are not yet sure whether it is Normal,
- // Rewriting or Modifying. The event is sent on if we switch to Modifying, or
- // discarded if the OSKey is released while in Rewriting mode.
- protocol::KeyEvent deferred_keydown_event_;
-
- // True while the |rewrite_keydown_event_| key is Rewriting, i.e. was followed
- // by one or more Rewritten key events, and not by any Modified events.
- bool deferred_key_is_rewriting_;
-
- // Stores the code of the OSKey while it is pressed for use as a Modifier.
- uint32 modifying_key_;
-
- DISALLOW_COPY_AND_ASSIGN(NormalizingInputFilterAsh);
-};
-
-} // namespace
-
-scoped_ptr<protocol::InputFilter> CreateNormalizingInputFilter(
- protocol::InputStub* input_stub) {
- return scoped_ptr<protocol::InputFilter>(
- new NormalizingInputFilterAsh(input_stub));
-}
-
-} // namespace remoting
diff --git a/remoting/client/plugin/normalizing_input_filter_ash_unittest.cc b/remoting/client/plugin/normalizing_input_filter_ash_unittest.cc
deleted file mode 100644
index e6ef6f9..0000000
--- a/remoting/client/plugin/normalizing_input_filter_ash_unittest.cc
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2013 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 "remoting/client/plugin/normalizing_input_filter.h"
-#include "remoting/proto/event.pb.h"
-#include "remoting/protocol/protocol_mock_objects.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::InSequence;
-using remoting::protocol::InputStub;
-using remoting::protocol::KeyEvent;
-using remoting::protocol::MockInputStub;
-using remoting::protocol::MouseEvent;
-
-namespace remoting {
-
-namespace {
-
-const unsigned int kUsbLeftOsKey = 0x0700e3;
-const unsigned int kUsbRightOsKey = 0x0700e7;
-
-const unsigned int kUsbFunctionKey = 0x07003a; // F1
-const unsigned int kUsbExtendedKey = 0x070049; // Insert
-const unsigned int kUsbOtherKey = 0x07002b; // Tab
-
-// A hardcoded value used to verify |lock_states| is preserved.
-static const uint32 kTestLockStates = protocol::KeyEvent::LOCK_STATES_NUMLOCK;
-
-MATCHER_P2(EqualsKeyEvent, usb_keycode, pressed, "") {
- return arg.usb_keycode() == static_cast<uint32>(usb_keycode) &&
- arg.pressed() == pressed &&
- arg.lock_states() == kTestLockStates;
-}
-
-KeyEvent MakeKeyEvent(uint32 keycode, bool pressed) {
- KeyEvent event;
- event.set_usb_keycode(keycode);
- event.set_pressed(pressed);
- event.set_lock_states(kTestLockStates);
- return event;
-}
-
-void PressAndReleaseKey(InputStub* input_stub, uint32 keycode) {
- input_stub->InjectKeyEvent(MakeKeyEvent(keycode, true));
- input_stub->InjectKeyEvent(MakeKeyEvent(keycode, false));
-}
-
-MATCHER_P2(EqualsMouseMoveEvent, x, y, "") {
- return arg.x() == x && arg.y() == y;
-}
-
-static MouseEvent MakeMouseMoveEvent(int x, int y) {
- MouseEvent event;
- event.set_x(x);
- event.set_y(y);
- return event;
-}
-
-} // namespace
-
-// Test OSKey press/release.
-TEST(NormalizingInputFilterAshTest, PressReleaseOsKey) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbRightOsKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbRightOsKey, false)));
- }
-
- // Inject press & release events for left & right OSKeys.
- PressAndReleaseKey(processor.get(), kUsbLeftOsKey);
- PressAndReleaseKey(processor.get(), kUsbRightOsKey);
-}
-
-// Test OSKey key repeat switches it to "modifying" mode.
-TEST(NormalizingInputFilterAshTest, OSKeyRepeats) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- }
-
- // Inject a press and repeats for the left OSKey, but don't release it, and
- // verify that the repeats result in press events.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
-}
-
-// Test OSKey press followed by function key press and release results in
-// just the function key events.
-TEST(NormalizingInputFilterAshTest, FunctionKey) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbFunctionKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbFunctionKey, false)));
- }
-
- // Hold the left OSKey while pressing & releasing the function key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- PressAndReleaseKey(processor.get(), kUsbFunctionKey);
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
-}
-
-// Test OSKey press followed by extended key press and release results in
-// just the function key events.
-TEST(NormalizingInputFilterAshTest, ExtendedKey) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, false)));
- }
-
- // Hold the left OSKey while pressing & releasing the function key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- PressAndReleaseKey(processor.get(), kUsbExtendedKey);
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
-}
-
-// Test OSKey press followed by non-function, non-extended key press and release
-// results in normal-looking sequence.
-TEST(NormalizingInputFilterAshTest, OtherKey) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, false)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
- }
-
- // Hold the left OSKey while pressing & releasing the function key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- PressAndReleaseKey(processor.get(), kUsbOtherKey);
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
-}
-
-// Test OSKey press followed by extended key press, then normal key press
-// results in OSKey switching to modifying mode for the normal key.
-TEST(NormalizingInputFilterAshTest, ExtendedThenOtherKey) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbExtendedKey, false)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, true)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbOtherKey, false)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
- }
-
- // Hold the left OSKey while pressing & releasing the function key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- PressAndReleaseKey(processor.get(), kUsbExtendedKey);
- PressAndReleaseKey(processor.get(), kUsbOtherKey);
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
-}
-
-// Test OSKey press followed by mouse event puts the OSKey into modifying mode.
-TEST(NormalizingInputFilterAshTest, MouseEvent) {
- MockInputStub stub;
- scoped_ptr<protocol::InputFilter> processor =
- CreateNormalizingInputFilter(&stub);
-
- {
- InSequence s;
-
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, true)));
- EXPECT_CALL(stub, InjectMouseEvent(EqualsMouseMoveEvent(0, 0)));
- EXPECT_CALL(stub, InjectKeyEvent(EqualsKeyEvent(kUsbLeftOsKey, false)));
- }
-
- // Hold the left OSKey while pressing & releasing the function key.
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, true));
- processor->InjectMouseEvent(MakeMouseMoveEvent(0, 0));
- processor->InjectKeyEvent(MakeKeyEvent(kUsbLeftOsKey, false));
-}
-
-} // namespace remoting