diff options
Diffstat (limited to 'remoting/host')
-rw-r--r-- | remoting/host/client_session_unittest.cc | 7 | ||||
-rw-r--r-- | remoting/host/desktop_environment.cc | 1 | ||||
-rw-r--r-- | remoting/host/event_executor.h | 3 | ||||
-rw-r--r-- | remoting/host/event_executor_fake.cc | 4 | ||||
-rw-r--r-- | remoting/host/event_executor_fake.h | 1 | ||||
-rw-r--r-- | remoting/host/event_executor_linux.cc | 187 | ||||
-rw-r--r-- | remoting/host/event_executor_mac.cc | 96 | ||||
-rw-r--r-- | remoting/host/event_executor_win.cc | 111 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.cc | 5 | ||||
-rw-r--r-- | remoting/host/host_mock_objects.h | 2 | ||||
-rw-r--r-- | remoting/host/win/session_event_executor.cc | 143 | ||||
-rw-r--r-- | remoting/host/win/session_event_executor.h | 39 |
12 files changed, 379 insertions, 220 deletions
diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc index 4678dbc..0a7cf48 100644 --- a/remoting/host/client_session_unittest.cc +++ b/remoting/host/client_session_unittest.cc @@ -82,7 +82,7 @@ class ClientSessionTest : public testing::Test { } virtual void TearDown() OVERRIDE { - // MockClientSessionEventHandler won't trigger StopAndDelete, so fake it. + // MockClientSessionEventHandler won't trigger Stop, so fake it. client_session_->Stop(base::Bind( &ClientSessionTest::OnClientStopped, base::Unretained(this))); @@ -183,7 +183,6 @@ TEST_F(ClientSessionTest, ClipboardStubFilter) { EXPECT_CALL(*event_executor_, InjectClipboardEvent(EqualsClipboardEvent( kMimeTypeTextUtf8, "b"))); EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); - EXPECT_CALL(*event_executor_, StopAndDeleteMock()); // This event should not get through to the clipboard stub, // because the client isn't authenticated yet. @@ -248,7 +247,6 @@ TEST_F(ClientSessionTest, InputStubFilter) { EXPECT_CALL(*event_executor_, InjectKeyEvent(EqualsUsbEvent(2, false))); EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(200, 201))); EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); - EXPECT_CALL(*event_executor_, StopAndDeleteMock()); // These events should not get through to the input stub, // because the client isn't authenticated yet. @@ -285,7 +283,6 @@ TEST_F(ClientSessionTest, LocalInputTest) { EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(100, 101))); EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseEvent(200, 201))); EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); - EXPECT_CALL(*event_executor_, StopAndDeleteMock()); client_session_->OnConnectionAuthenticated(client_session_->connection()); client_session_->OnConnectionChannelsConnected(client_session_->connection()); @@ -330,7 +327,6 @@ TEST_F(ClientSessionTest, RestoreEventState) { EXPECT_CALL(*event_executor_, InjectMouseEvent(EqualsMouseButtonEvent( protocol::MouseEvent::BUTTON_LEFT, false))); EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); - EXPECT_CALL(*event_executor_, StopAndDeleteMock()); client_session_->OnConnectionAuthenticated(client_session_->connection()); client_session_->OnConnectionChannelsConnected(client_session_->connection()); @@ -350,7 +346,6 @@ TEST_F(ClientSessionTest, ClampMouseEvents) { Expectation connected = EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)); EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); - EXPECT_CALL(*event_executor_, StopAndDeleteMock()); client_session_->OnConnectionAuthenticated(client_session_->connection()); client_session_->OnConnectionChannelsConnected(client_session_->connection()); diff --git a/remoting/host/desktop_environment.cc b/remoting/host/desktop_environment.cc index d8935fc..aef55d1 100644 --- a/remoting/host/desktop_environment.cc +++ b/remoting/host/desktop_environment.cc @@ -22,7 +22,6 @@ DesktopEnvironment::DesktopEnvironment( } DesktopEnvironment::~DesktopEnvironment() { - event_executor_.release()->StopAndDelete(); } void DesktopEnvironment::Start( diff --git a/remoting/host/event_executor.h b/remoting/host/event_executor.h index 1032367..28dd559 100644 --- a/remoting/host/event_executor.h +++ b/remoting/host/event_executor.h @@ -30,9 +30,6 @@ class EventExecutor : public protocol::ClipboardStub, // Initialises any objects needed to execute events. virtual void Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) = 0; - - // Destroys any objects constructed by Start() and deletes |this|. - virtual void StopAndDelete() = 0; }; } // namespace remoting diff --git a/remoting/host/event_executor_fake.cc b/remoting/host/event_executor_fake.cc index a86ab4b..df8155e 100644 --- a/remoting/host/event_executor_fake.cc +++ b/remoting/host/event_executor_fake.cc @@ -26,8 +26,4 @@ void EventExecutorFake::Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) { } -void EventExecutorFake::StopAndDelete() { - delete this; -} - } // namespace remoting diff --git a/remoting/host/event_executor_fake.h b/remoting/host/event_executor_fake.h index 2a7d906..4172d4e 100644 --- a/remoting/host/event_executor_fake.h +++ b/remoting/host/event_executor_fake.h @@ -25,7 +25,6 @@ class EventExecutorFake : public EventExecutor { virtual void Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - virtual void StopAndDelete() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(EventExecutorFake); diff --git a/remoting/host/event_executor_linux.cc b/remoting/host/event_executor_linux.cc index 305420c..b3176e3 100644 --- a/remoting/host/event_executor_linux.cc +++ b/remoting/host/event_executor_linux.cc @@ -47,8 +47,7 @@ class EventExecutorLinux : public EventExecutor { bool Init(); // Clipboard stub interface. - virtual void InjectClipboardEvent(const ClipboardEvent& event) - OVERRIDE; + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; // InputStub interface. virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; @@ -57,48 +56,107 @@ class EventExecutorLinux : public EventExecutor { // EventExecutor interface. virtual void Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - virtual void StopAndDelete() OVERRIDE; private: - // Number of buttons we support. - // Left, Right, Middle, VScroll Up/Down, HScroll Left/Right. - static const int kNumPointerButtons = 7; + // The actual implementation resides in EventExecutorWin::Core class. + class Core : public base::RefCountedThreadSafe<Core>, public EventExecutor { + public: + explicit Core(scoped_refptr<base::SingleThreadTaskRunner> task_runner); - void InitClipboard(); + bool Init(); - // |mode| is one of the AutoRepeatModeOn, AutoRepeatModeOff, - // AutoRepeatModeDefault constants defined by the XChangeKeyboardControl() - // API. - void SetAutoRepeatForKey(int keycode, int mode); - void InjectScrollWheelClicks(int button, int count); - // Compensates for global button mappings and resets the XTest device mapping. - void InitMouseButtonMap(); - int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); - int HorizontalScrollWheelToX11ButtonNumber(int dx); - int VerticalScrollWheelToX11ButtonNumber(int dy); + // Clipboard stub interface. + virtual void InjectClipboardEvent(const ClipboardEvent& event) + OVERRIDE; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + // InputStub interface. + virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; + virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; - std::set<int> pressed_keys_; - SkIPoint latest_mouse_position_; - float wheel_ticks_x_; - float wheel_ticks_y_; + // EventExecutor interface. + virtual void Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - // X11 graphics context. - Display* display_; - Window root_window_; + void Stop(); - int test_event_base_; - int test_error_base_; + private: + friend class base::RefCountedThreadSafe<Core>; + virtual ~Core(); - int pointer_button_map_[kNumPointerButtons]; + void InitClipboard(); - scoped_ptr<Clipboard> clipboard_; + // |mode| is one of the AutoRepeatModeOn, AutoRepeatModeOff, + // AutoRepeatModeDefault constants defined by the XChangeKeyboardControl() + // API. + void SetAutoRepeatForKey(int keycode, int mode); + void InjectScrollWheelClicks(int button, int count); + // Compensates for global button mappings and resets the XTest device + // mapping. + void InitMouseButtonMap(); + int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); + int HorizontalScrollWheelToX11ButtonNumber(int dx); + int VerticalScrollWheelToX11ButtonNumber(int dy); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + std::set<int> pressed_keys_; + SkIPoint latest_mouse_position_; + float wheel_ticks_x_; + float wheel_ticks_y_; + + // X11 graphics context. + Display* display_; + Window root_window_; + + int test_event_base_; + int test_error_base_; + + // Number of buttons we support. + // Left, Right, Middle, VScroll Up/Down, HScroll Left/Right. + static const int kNumPointerButtons = 7; + + int pointer_button_map_[kNumPointerButtons]; + + scoped_ptr<Clipboard> clipboard_; + + DISALLOW_COPY_AND_ASSIGN(Core); + }; + + scoped_refptr<Core> core_; DISALLOW_COPY_AND_ASSIGN(EventExecutorLinux); }; EventExecutorLinux::EventExecutorLinux( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + core_ = new Core(task_runner); +} +EventExecutorLinux::~EventExecutorLinux() { + core_->Stop(); +} + +bool EventExecutorLinux::Init() { + return core_->Init(); +} + +void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) { + core_->InjectClipboardEvent(event); +} + +void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { + core_->InjectKeyEvent(event); +} + +void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { + core_->InjectMouseEvent(event); +} + +void EventExecutorLinux::Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) { + core_->Start(client_clipboard.Pass()); +} + +EventExecutorLinux::Core::Core( scoped_refptr<base::SingleThreadTaskRunner> task_runner) : task_runner_(task_runner), latest_mouse_position_(SkIPoint::Make(-1, -1)), @@ -107,19 +165,12 @@ EventExecutorLinux::EventExecutorLinux( display_(XOpenDisplay(NULL)), root_window_(BadValue) { #if defined(REMOTING_HOST_LINUX_CLIPBOARD) - if (!task_runner_->BelongsToCurrentThread()) { - task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorLinux::InitClipboard, base::Unretained(this))); - } + if (!task_runner_->BelongsToCurrentThread()) + task_runner_->PostTask(FROM_HERE, base::Bind(&Core::InitClipboard, this)); #endif // REMOTING_HOST_LINUX_CLIPBOARD } -EventExecutorLinux::~EventExecutorLinux() { - CHECK(pressed_keys_.empty()); -} - -bool EventExecutorLinux::Init() { +bool EventExecutorLinux::Core::Init() { CHECK(display_); root_window_ = RootWindow(display_, DefaultScreen(display_)); @@ -140,13 +191,12 @@ bool EventExecutorLinux::Init() { return true; } -void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) { +void EventExecutorLinux::Core::InjectClipboardEvent( + const ClipboardEvent& event) { #if defined(REMOTING_HOST_LINUX_CLIPBOARD) if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorLinux::InjectClipboardEvent, - base::Unretained(this), event)); + FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); return; } @@ -154,16 +204,14 @@ void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) { #endif // REMOTING_HOST_LINUX_CLIPBOARD } -void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { +void EventExecutorLinux::Core::InjectKeyEvent(const KeyEvent& event) { // HostEventDispatcher should filter events missing the pressed field. DCHECK(event.has_pressed()); DCHECK(event.has_usb_keycode()); if (!task_runner_->BelongsToCurrentThread()) { - task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorLinux::InjectKeyEvent, base::Unretained(this), - event)); + task_runner_->PostTask(FROM_HERE, + base::Bind(&Core::InjectKeyEvent, this, event)); return; } @@ -201,19 +249,23 @@ void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { XFlush(display_); } -void EventExecutorLinux::InitClipboard() { +EventExecutorLinux::Core::~Core() { + CHECK(pressed_keys_.empty()); +} + +void EventExecutorLinux::Core::InitClipboard() { DCHECK(task_runner_->BelongsToCurrentThread()); clipboard_ = Clipboard::Create(); } -void EventExecutorLinux::SetAutoRepeatForKey(int keycode, int mode) { +void EventExecutorLinux::Core::SetAutoRepeatForKey(int keycode, int mode) { XKeyboardControl control; control.key = keycode; control.auto_repeat_mode = mode; XChangeKeyboardControl(display_, KBKey | KBAutoRepeatMode, &control); } -void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) { +void EventExecutorLinux::Core::InjectScrollWheelClicks(int button, int count) { if (button < 0) { LOG(WARNING) << "Ignoring unmapped scroll wheel button"; return; @@ -225,12 +277,10 @@ void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) { } } -void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { +void EventExecutorLinux::Core::InjectMouseEvent(const MouseEvent& event) { if (!task_runner_->BelongsToCurrentThread()) { - task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorLinux::InjectMouseEvent, - base::Unretained(this), event)); + task_runner_->PostTask(FROM_HERE, + base::Bind(&Core::InjectMouseEvent, this, event)); return; } @@ -301,7 +351,7 @@ void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { XFlush(display_); } -void EventExecutorLinux::InitMouseButtonMap() { +void EventExecutorLinux::Core::InitMouseButtonMap() { // TODO(rmsousa): Run this on global/device mapping change events. // Do not touch global pointer mapping, since this may affect the local user. @@ -378,7 +428,7 @@ void EventExecutorLinux::InitMouseButtonMap() { XCloseDevice(display_, device); } -int EventExecutorLinux::MouseButtonToX11ButtonNumber( +int EventExecutorLinux::Core::MouseButtonToX11ButtonNumber( MouseEvent::MouseButton button) { switch (button) { case MouseEvent::BUTTON_LEFT: @@ -396,25 +446,23 @@ int EventExecutorLinux::MouseButtonToX11ButtonNumber( } } -int EventExecutorLinux::HorizontalScrollWheelToX11ButtonNumber(int dx) { +int EventExecutorLinux::Core::HorizontalScrollWheelToX11ButtonNumber(int dx) { return (dx > 0 ? pointer_button_map_[5] : pointer_button_map_[6]); } -int EventExecutorLinux::VerticalScrollWheelToX11ButtonNumber(int dy) { +int EventExecutorLinux::Core::VerticalScrollWheelToX11ButtonNumber(int dy) { // Positive y-values are wheel scroll-up events (button 4), negative y-values // are wheel scroll-down events (button 5). return (dy > 0 ? pointer_button_map_[3] : pointer_button_map_[4]); } -void EventExecutorLinux::Start( +void EventExecutorLinux::Core::Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) { if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( FROM_HERE, - base::Bind(&EventExecutorLinux::Start, - base::Unretained(this), - base::Passed(&client_clipboard))); + base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); return; } @@ -424,8 +472,15 @@ void EventExecutorLinux::Start( #endif // REMOTING_HOST_LINUX_CLIPBOARD } -void EventExecutorLinux::StopAndDelete() { - delete this; +void EventExecutorLinux::Core::Stop() { +#if defined(REMOTING_HOST_LINUX_CLIPBOARD) + if (!task_runner_->BelongsToCurrentThread()) { + task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); + return; + } + + clipboard_->Stop(); +#endif // REMOTING_HOST_LINUX_CLIPBOARD } } // namespace diff --git a/remoting/host/event_executor_mac.cc b/remoting/host/event_executor_mac.cc index fffc598..018360f 100644 --- a/remoting/host/event_executor_mac.cc +++ b/remoting/host/event_executor_mac.cc @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/location.h" #include "base/mac/scoped_cftyperef.h" +#include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "remoting/host/clipboard.h" #include "remoting/proto/internal.pb.h" @@ -46,8 +47,9 @@ SkIRect CGRectToSkIRect(const CGRect& rect) { // A class to generate events on Mac. class EventExecutorMac : public EventExecutor { public: - EventExecutorMac(scoped_refptr<base::SingleThreadTaskRunner> task_runner); - virtual ~EventExecutorMac() {} + explicit EventExecutorMac( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + virtual ~EventExecutorMac(); // ClipboardStub interface. virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; @@ -59,18 +61,70 @@ class EventExecutorMac : public EventExecutor { // EventExecutor interface. virtual void Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - virtual void StopAndDelete() OVERRIDE; private: - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - SkIPoint mouse_pos_; - uint32 mouse_button_state_; - scoped_ptr<Clipboard> clipboard_; + // The actual implementation resides in EventExecutorWin::Core class. + class Core : public base::RefCountedThreadSafe<Core>, public EventExecutor { + public: + explicit Core(scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // ClipboardStub interface. + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + + // InputStub interface. + virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; + virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; + + // EventExecutor interface. + virtual void Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; + + void Stop(); + + private: + friend class base::RefCountedThreadSafe<Core>; + virtual ~Core(); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + SkIPoint mouse_pos_; + uint32 mouse_button_state_; + scoped_ptr<Clipboard> clipboard_; + + DISALLOW_COPY_AND_ASSIGN(Core); + }; + + scoped_refptr<Core> core_; DISALLOW_COPY_AND_ASSIGN(EventExecutorMac); }; EventExecutorMac::EventExecutorMac( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + core_ = new Core(task_runner); +} + +EventExecutorMac::~EventExecutorMac() { + core_->Stop(); +} + +void EventExecutorMac::InjectClipboardEvent(const ClipboardEvent& event) { + core_->InjectClipboardEvent(event); +} + +void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { + core_->InjectKeyEvent(event); +} + +void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { + core_->InjectMouseEvent(event); +} + +void EventExecutorMac::Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) { + core_->Start(client_clipboard.Pass()); +} + +EventExecutorMac::Core::Core( scoped_refptr<base::SingleThreadTaskRunner> task_runner) : task_runner_(task_runner), mouse_button_state_(0), @@ -89,20 +143,17 @@ EventExecutorMac::EventExecutorMac( #pragma clang diagnostic pop } -void EventExecutorMac::InjectClipboardEvent(const ClipboardEvent& event) { +void EventExecutorMac::Core::InjectClipboardEvent(const ClipboardEvent& event) { if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorMac::InjectClipboardEvent, - base::Unretained(this), - event)); + FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); return; } clipboard_->InjectClipboardEvent(event); } -void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { +void EventExecutorMac::Core::InjectKeyEvent(const KeyEvent& event) { // HostEventDispatcher should filter events missing the pressed field. DCHECK(event.has_pressed()); DCHECK(event.has_usb_keycode()); @@ -127,7 +178,7 @@ void EventExecutorMac::InjectKeyEvent(const KeyEvent& event) { } } -void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { +void EventExecutorMac::Core::InjectMouseEvent(const MouseEvent& event) { if (event.has_x() && event.has_y()) { // On multi-monitor systems (0,0) refers to the top-left of the "main" // display, whereas our coordinate scheme places (0,0) at the top-left of @@ -222,31 +273,28 @@ void EventExecutorMac::InjectMouseEvent(const MouseEvent& event) { } } -void EventExecutorMac::Start( +void EventExecutorMac::Core::Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) { if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( FROM_HERE, - base::Bind(&EventExecutorMac::Start, - base::Unretained(this), - base::Passed(&client_clipboard))); + base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); return; } clipboard_->Start(client_clipboard.Pass()); } -void EventExecutorMac::StopAndDelete() { +void EventExecutorMac::Core::Stop() { if (!task_runner_->BelongsToCurrentThread()) { - task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorMac::StopAndDelete, - base::Unretained(this))); + task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); return; } clipboard_->Stop(); - delete this; +} + +EventExecutorMac::Core::~Core() { } } // namespace diff --git a/remoting/host/event_executor_win.cc b/remoting/host/event_executor_win.cc index 83401ad..6f767b0 100644 --- a/remoting/host/event_executor_win.cc +++ b/remoting/host/event_executor_win.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/compiler_specific.h" #include "base/location.h" +#include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "remoting/host/clipboard.h" #include "remoting/proto/event.pb.h" @@ -34,7 +35,7 @@ class EventExecutorWin : public EventExecutor { public: EventExecutorWin(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); - virtual ~EventExecutorWin() {} + virtual ~EventExecutorWin(); // ClipboardStub interface. virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; @@ -46,92 +47,136 @@ class EventExecutorWin : public EventExecutor { // EventExecutor interface. virtual void Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - virtual void StopAndDelete() OVERRIDE; private: - void HandleKey(const KeyEvent& event); - void HandleMouse(const MouseEvent& event); + // The actual implementation resides in EventExecutorWin::Core class. + class Core : public base::RefCountedThreadSafe<Core>, public EventExecutor { + public: + Core(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; - scoped_ptr<Clipboard> clipboard_; + // ClipboardStub interface. + virtual void InjectClipboardEvent(const ClipboardEvent& event) OVERRIDE; + + // InputStub interface. + virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; + virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; + + // EventExecutor interface. + virtual void Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; + + void Stop(); + + private: + friend class base::RefCountedThreadSafe<Core>; + virtual ~Core(); + + void HandleKey(const KeyEvent& event); + void HandleMouse(const MouseEvent& event); + + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; + scoped_ptr<Clipboard> clipboard_; + + DISALLOW_COPY_AND_ASSIGN(Core); + }; + + scoped_refptr<Core> core_; DISALLOW_COPY_AND_ASSIGN(EventExecutorWin); }; EventExecutorWin::EventExecutorWin( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { + core_ = new Core(main_task_runner, ui_task_runner); +} + +EventExecutorWin::~EventExecutorWin() { + core_->Stop(); +} + +void EventExecutorWin::InjectClipboardEvent(const ClipboardEvent& event) { + core_->InjectClipboardEvent(event); +} + +void EventExecutorWin::InjectKeyEvent(const KeyEvent& event) { + core_->InjectKeyEvent(event); +} + +void EventExecutorWin::InjectMouseEvent(const MouseEvent& event) { + core_->InjectMouseEvent(event); +} + +void EventExecutorWin::Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) { + core_->Start(client_clipboard.Pass()); +} + +EventExecutorWin::Core::Core( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) : main_task_runner_(main_task_runner), ui_task_runner_(ui_task_runner), clipboard_(Clipboard::Create()) { } -void EventExecutorWin::InjectClipboardEvent(const ClipboardEvent& event) { +void EventExecutorWin::Core::InjectClipboardEvent(const ClipboardEvent& event) { if (!ui_task_runner_->BelongsToCurrentThread()) { ui_task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorWin::InjectClipboardEvent, - base::Unretained(this), - event)); + FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); return; } clipboard_->InjectClipboardEvent(event); } -void EventExecutorWin::InjectKeyEvent(const KeyEvent& event) { +void EventExecutorWin::Core::InjectKeyEvent(const KeyEvent& event) { if (!main_task_runner_->BelongsToCurrentThread()) { - main_task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorWin::InjectKeyEvent, base::Unretained(this), - event)); + main_task_runner_->PostTask(FROM_HERE, + base::Bind(&Core::InjectKeyEvent, this, event)); return; } HandleKey(event); } -void EventExecutorWin::InjectMouseEvent(const MouseEvent& event) { +void EventExecutorWin::Core::InjectMouseEvent(const MouseEvent& event) { if (!main_task_runner_->BelongsToCurrentThread()) { main_task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorWin::InjectMouseEvent, base::Unretained(this), - event)); + FROM_HERE, base::Bind(&Core::InjectMouseEvent, this, event)); return; } HandleMouse(event); } -void EventExecutorWin::Start( +void EventExecutorWin::Core::Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) { if (!ui_task_runner_->BelongsToCurrentThread()) { ui_task_runner_->PostTask( FROM_HERE, - base::Bind(&EventExecutorWin::Start, - base::Unretained(this), - base::Passed(&client_clipboard))); + base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); return; } clipboard_->Start(client_clipboard.Pass()); } -void EventExecutorWin::StopAndDelete() { +void EventExecutorWin::Core::Stop() { if (!ui_task_runner_->BelongsToCurrentThread()) { - ui_task_runner_->PostTask( - FROM_HERE, - base::Bind(&EventExecutorWin::StopAndDelete, - base::Unretained(this))); + ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); return; } clipboard_->Stop(); - delete this; } -void EventExecutorWin::HandleKey(const KeyEvent& event) { +EventExecutorWin::Core::~Core() { +} + +void EventExecutorWin::Core::HandleKey(const KeyEvent& event) { // HostEventDispatcher should filter events missing the pressed field. DCHECK(event.has_pressed()); DCHECK(event.has_usb_keycode()); @@ -170,7 +215,7 @@ void EventExecutorWin::HandleKey(const KeyEvent& event) { } } -void EventExecutorWin::HandleMouse(const MouseEvent& event) { +void EventExecutorWin::Core::HandleMouse(const MouseEvent& event) { // Reset the system idle suspend timeout. SetThreadExecutionState(ES_SYSTEM_REQUIRED); diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc index 399a5a6..3f5cfee 100644 --- a/remoting/host/host_mock_objects.cc +++ b/remoting/host/host_mock_objects.cc @@ -46,11 +46,6 @@ void MockEventExecutor::Start( StartPtr(client_clipboard.get()); } -void MockEventExecutor::StopAndDelete() { - StopAndDeleteMock(); - delete this; -} - MockDisconnectWindow::MockDisconnectWindow() {} MockDisconnectWindow::~MockDisconnectWindow() {} diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h index 8d6d1e2..d5ebcdb 100644 --- a/remoting/host/host_mock_objects.h +++ b/remoting/host/host_mock_objects.h @@ -145,10 +145,8 @@ class MockEventExecutor : public EventExecutor { MOCK_METHOD1(InjectMouseEvent, void(const protocol::MouseEvent& event)); MOCK_METHOD1(StartPtr, void(protocol::ClipboardStub* client_clipboard)); - MOCK_METHOD0(StopAndDeleteMock, void()); void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard); - void StopAndDelete(); private: DISALLOW_COPY_AND_ASSIGN(MockEventExecutor); diff --git a/remoting/host/win/session_event_executor.cc b/remoting/host/win/session_event_executor.cc index 1c5a2d4..f097014 100644 --- a/remoting/host/win/session_event_executor.cc +++ b/remoting/host/win/session_event_executor.cc @@ -4,15 +4,18 @@ #include "remoting/host/win/session_event_executor.h" +#include <set> #include <string> #include "base/bind.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/win/windows_version.h" #include "remoting/host/sas_injector.h" #include "remoting/host/win/desktop.h" +#include "remoting/host/win/scoped_thread_desktop.h" #include "remoting/proto/event.pb.h" namespace { @@ -40,71 +43,95 @@ using protocol::ClipboardEvent; using protocol::MouseEvent; using protocol::KeyEvent; -SessionEventExecutorWin::SessionEventExecutorWin( +class SessionEventExecutorWin::Core + : public base::RefCountedThreadSafe<SessionEventExecutorWin::Core>, + public EventExecutor { + public: + Core( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_ptr<EventExecutor> nested_executor, + scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, + const base::Closure& inject_sas); + + // EventExecutor implementation. + virtual void Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; + + // protocol::ClipboardStub implementation. + virtual void InjectClipboardEvent( + const protocol::ClipboardEvent& event) OVERRIDE; + + // protocol::InputStub implementation. + virtual void InjectKeyEvent(const protocol::KeyEvent& event) OVERRIDE; + virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE; + + private: + friend class base::RefCountedThreadSafe<Core>; + virtual ~Core(); + + // Switches to the desktop receiving a user input if different from + // the current one. + void SwitchToInputDesktop(); + + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; + + // Pointer to the next event executor. + scoped_ptr<EventExecutor> nested_executor_; + + scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_; + + ScopedThreadDesktop desktop_; + + // Used to inject Secure Attention Sequence on Vista+. + base::Closure inject_sas_; + + // Used to inject Secure Attention Sequence on XP. + scoped_ptr<SasInjector> sas_injector_; + + // Keys currently pressed by the client, used to detect Ctrl-Alt-Del. + std::set<uint32> pressed_keys_; + + DISALLOW_COPY_AND_ASSIGN(Core); +}; + +SessionEventExecutorWin::Core::Core( scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, scoped_ptr<EventExecutor> nested_executor, scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, const base::Closure& inject_sas) - : nested_executor_(nested_executor.Pass()), - input_task_runner_(input_task_runner), + : input_task_runner_(input_task_runner), + nested_executor_(nested_executor.Pass()), inject_sas_task_runner_(inject_sas_task_runner), - inject_sas_(inject_sas), - ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), - weak_ptr_(weak_ptr_factory_.GetWeakPtr()) { - // Let |weak_ptr_| be used on the |input_task_runner_| thread. - // |weak_ptr_| and |weak_ptr_factory_| share a ThreadChecker, so the - // following line affects both of them. - weak_ptr_factory_.DetachFromThread(); -} - -SessionEventExecutorWin::~SessionEventExecutorWin() { + inject_sas_(inject_sas) { } -void SessionEventExecutorWin::Start( +void SessionEventExecutorWin::Core::Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) { if (!input_task_runner_->BelongsToCurrentThread()) { input_task_runner_->PostTask( FROM_HERE, - base::Bind(&SessionEventExecutorWin::Start, - weak_ptr_, base::Passed(&client_clipboard))); + base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); return; } nested_executor_->Start(client_clipboard.Pass()); } -void SessionEventExecutorWin::StopAndDelete() { - if (!input_task_runner_->BelongsToCurrentThread()) { - input_task_runner_->PostTask( - FROM_HERE, - base::Bind(&SessionEventExecutorWin::StopAndDelete, - weak_ptr_)); - return; - } - - nested_executor_.release()->StopAndDelete(); - delete this; -} - -void SessionEventExecutorWin::InjectClipboardEvent( +void SessionEventExecutorWin::Core::InjectClipboardEvent( const ClipboardEvent& event) { if (!input_task_runner_->BelongsToCurrentThread()) { input_task_runner_->PostTask( - FROM_HERE, - base::Bind(&SessionEventExecutorWin::InjectClipboardEvent, - weak_ptr_, event)); + FROM_HERE, base::Bind(&Core::InjectClipboardEvent, this, event)); return; } nested_executor_->InjectClipboardEvent(event); } -void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) { +void SessionEventExecutorWin::Core::InjectKeyEvent(const KeyEvent& event) { if (!input_task_runner_->BelongsToCurrentThread()) { input_task_runner_->PostTask( - FROM_HERE, - base::Bind(&SessionEventExecutorWin::InjectKeyEvent, - weak_ptr_, event)); + FROM_HERE, base::Bind(&Core::InjectKeyEvent, this, event)); return; } @@ -138,12 +165,10 @@ void SessionEventExecutorWin::InjectKeyEvent(const KeyEvent& event) { nested_executor_->InjectKeyEvent(event); } -void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) { +void SessionEventExecutorWin::Core::InjectMouseEvent(const MouseEvent& event) { if (!input_task_runner_->BelongsToCurrentThread()) { input_task_runner_->PostTask( - FROM_HERE, - base::Bind(&SessionEventExecutorWin::InjectMouseEvent, - weak_ptr_, event)); + FROM_HERE, base::Bind(&Core::InjectMouseEvent, this, event)); return; } @@ -151,7 +176,10 @@ void SessionEventExecutorWin::InjectMouseEvent(const MouseEvent& event) { nested_executor_->InjectMouseEvent(event); } -void SessionEventExecutorWin::SwitchToInputDesktop() { +SessionEventExecutorWin::Core::~Core() { +} + +void SessionEventExecutorWin::Core::SwitchToInputDesktop() { // Switch to the desktop receiving user input if different from the current // one. scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop(); @@ -162,4 +190,35 @@ void SessionEventExecutorWin::SwitchToInputDesktop() { } } +SessionEventExecutorWin::SessionEventExecutorWin( + scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, + scoped_ptr<EventExecutor> nested_executor, + scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, + const base::Closure& inject_sas) { + core_ = new Core(input_task_runner, nested_executor.Pass(), + inject_sas_task_runner, inject_sas); +} + +SessionEventExecutorWin::~SessionEventExecutorWin() { +} + +void SessionEventExecutorWin::Start( + scoped_ptr<protocol::ClipboardStub> client_clipboard) { + core_->Start(client_clipboard.Pass()); +} + +void SessionEventExecutorWin::InjectClipboardEvent( + const protocol::ClipboardEvent& event) { + core_->InjectClipboardEvent(event); +} + +void SessionEventExecutorWin::InjectKeyEvent(const protocol::KeyEvent& event) { + core_->InjectKeyEvent(event); +} + +void SessionEventExecutorWin::InjectMouseEvent( + const protocol::MouseEvent& event) { + core_->InjectMouseEvent(event); +} + } // namespace remoting diff --git a/remoting/host/win/session_event_executor.h b/remoting/host/win/session_event_executor.h index 3fa3ed5..d9fef51 100644 --- a/remoting/host/win/session_event_executor.h +++ b/remoting/host/win/session_event_executor.h @@ -5,14 +5,11 @@ #ifndef REMOTING_HOST_WIN_SESSION_EVENT_EXECUTOR_H_ #define REMOTING_HOST_WIN_SESSION_EVENT_EXECUTOR_H_ -#include <set> - #include "base/basictypes.h" -#include "base/callback.h" +#include "base/callback_forward.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" +#include "base/memory/ref_counted.h" #include "remoting/host/event_executor.h" -#include "remoting/host/win/scoped_thread_desktop.h" namespace base { class SingleThreadTaskRunner; @@ -20,8 +17,6 @@ class SingleThreadTaskRunner; namespace remoting { -class SasInjector; - // Monitors and passes key/mouse events to a nested event executor. Injects // Secure Attention Sequence (SAS) when Ctrl+Alt+Del key combination has been // detected. @@ -34,12 +29,11 @@ class SessionEventExecutorWin : public EventExecutor { scoped_ptr<EventExecutor> nested_executor, scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner, const base::Closure& inject_sas); - ~SessionEventExecutorWin(); + virtual ~SessionEventExecutorWin(); // EventExecutor implementation. virtual void Start( scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; - virtual void StopAndDelete() OVERRIDE; // protocol::ClipboardStub implementation. virtual void InjectClipboardEvent( @@ -50,30 +44,9 @@ class SessionEventExecutorWin : public EventExecutor { virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE; private: - // Switches to the desktop receiving a user input if different from - // the current one. - void SwitchToInputDesktop(); - - scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; - - // Pointer to the next event executor. - scoped_ptr<EventExecutor> nested_executor_; - - scoped_refptr<base::SingleThreadTaskRunner> inject_sas_task_runner_; - - ScopedThreadDesktop desktop_; - - // Used to inject Secure Attention Sequence on Vista+. - base::Closure inject_sas_; - - // Used to inject Secure Attention Sequence on XP. - scoped_ptr<SasInjector> sas_injector_; - - // Keys currently pressed by the client, used to detect Ctrl-Alt-Del. - std::set<uint32> pressed_keys_; - - base::WeakPtrFactory<SessionEventExecutorWin> weak_ptr_factory_; - base::WeakPtr<SessionEventExecutorWin> weak_ptr_; + // The actual implementation resides in SessionEventExecutorWin::Core class. + class Core; + scoped_refptr<Core> core_; DISALLOW_COPY_AND_ASSIGN(SessionEventExecutorWin); }; |