| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/local_input_monitor.h" | 5 #include "remoting/host/local_input_monitor.h" |
| 6 | 6 |
| 7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/mac/scoped_cftyperef.h" | 14 #include "base/mac/scoped_cftyperef.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/synchronization/lock.h" | 17 #include "base/synchronization/lock.h" |
| 18 #include "remoting/host/mouse_move_observer.h" | 18 #include "base/threading/non_thread_safe.h" |
| 19 #include "remoting/host/client_session_control.h" |
| 19 #include "third_party/skia/include/core/SkPoint.h" | 20 #include "third_party/skia/include/core/SkPoint.h" |
| 20 #import "third_party/GTM/AppKit/GTMCarbonEvent.h" | 21 #import "third_party/GTM/AppKit/GTMCarbonEvent.h" |
| 21 | 22 |
| 22 // Esc Key Code is 53. | 23 // Esc Key Code is 53. |
| 23 // http://boredzo.org/blog/wp-content/uploads/2007/05/IMTx-virtual-keycodes.pdf | 24 // http://boredzo.org/blog/wp-content/uploads/2007/05/IMTx-virtual-keycodes.pdf |
| 24 static const NSUInteger kEscKeyCode = 53; | 25 static const NSUInteger kEscKeyCode = 53; |
| 25 | 26 |
| 26 namespace remoting { | 27 namespace remoting { |
| 27 namespace { | 28 namespace { |
| 28 | 29 |
| 29 class LocalInputMonitorMac : public LocalInputMonitor { | 30 class LocalInputMonitorMac : public base::NonThreadSafe, |
| 31 public LocalInputMonitor { |
| 30 public: | 32 public: |
| 31 // Invoked by LocalInputMonitorManager. | 33 // Invoked by LocalInputMonitorManager. |
| 32 class EventHandler { | 34 class EventHandler { |
| 33 public: | 35 public: |
| 34 virtual ~EventHandler() {} | 36 virtual ~EventHandler() {} |
| 35 | 37 |
| 36 virtual void OnLocalMouseMoved(const SkIPoint& position) = 0; | 38 virtual void OnLocalMouseMoved(const SkIPoint& position) = 0; |
| 37 virtual void OnDisconnectShortcut() = 0; | 39 virtual void OnDisconnectShortcut() = 0; |
| 38 }; | 40 }; |
| 39 | 41 |
| 40 LocalInputMonitorMac( | 42 LocalInputMonitorMac( |
| 41 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 43 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 42 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); | 44 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 45 base::WeakPtr<ClientSessionControl> client_session_control); |
| 43 virtual ~LocalInputMonitorMac(); | 46 virtual ~LocalInputMonitorMac(); |
| 44 | 47 |
| 45 virtual void Start(MouseMoveObserver* mouse_move_observer, | |
| 46 const base::Closure& disconnect_callback) OVERRIDE; | |
| 47 virtual void Stop() OVERRIDE; | |
| 48 | |
| 49 private: | 48 private: |
| 50 // The actual implementation resides in LocalInputMonitorMac::Core class. | 49 // The actual implementation resides in LocalInputMonitorMac::Core class. |
| 51 class Core; | 50 class Core; |
| 52 scoped_refptr<Core> core_; | 51 scoped_refptr<Core> core_; |
| 53 | 52 |
| 54 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorMac); | 53 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorMac); |
| 55 }; | 54 }; |
| 56 | 55 |
| 57 } // namespace | 56 } // namespace |
| 58 } // namespace remoting | 57 } // namespace remoting |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 @end | 153 @end |
| 155 | 154 |
| 156 namespace remoting { | 155 namespace remoting { |
| 157 namespace { | 156 namespace { |
| 158 | 157 |
| 159 class LocalInputMonitorMac::Core | 158 class LocalInputMonitorMac::Core |
| 160 : public base::RefCountedThreadSafe<Core>, | 159 : public base::RefCountedThreadSafe<Core>, |
| 161 public EventHandler { | 160 public EventHandler { |
| 162 public: | 161 public: |
| 163 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 162 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 164 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner); | 163 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 164 base::WeakPtr<ClientSessionControl> client_session_control); |
| 165 | 165 |
| 166 void Start(MouseMoveObserver* mouse_move_observer, | 166 void Start(); |
| 167 const base::Closure& disconnect_callback); | |
| 168 void Stop(); | 167 void Stop(); |
| 169 | 168 |
| 170 private: | 169 private: |
| 171 friend class base::RefCountedThreadSafe<Core>; | 170 friend class base::RefCountedThreadSafe<Core>; |
| 172 virtual ~Core(); | 171 virtual ~Core(); |
| 173 | 172 |
| 174 void StartOnUiThread(); | 173 void StartOnUiThread(); |
| 175 void StopOnUiThread(); | 174 void StopOnUiThread(); |
| 176 | 175 |
| 177 // EventHandler interface. | 176 // EventHandler interface. |
| 178 virtual void OnLocalMouseMoved(const SkIPoint& position) OVERRIDE; | 177 virtual void OnLocalMouseMoved(const SkIPoint& position) OVERRIDE; |
| 179 virtual void OnDisconnectShortcut() OVERRIDE; | 178 virtual void OnDisconnectShortcut() OVERRIDE; |
| 180 | 179 |
| 181 // Task runner on which public methods of this class must be called. | 180 // Task runner on which public methods of this class must be called. |
| 182 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; | 181 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
| 183 | 182 |
| 184 // Task runner on which |window_| is created. | 183 // Task runner on which |window_| is created. |
| 185 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; | 184 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
| 186 | 185 |
| 187 LocalInputMonitorManager* manager_; | 186 LocalInputMonitorManager* manager_; |
| 188 | 187 |
| 189 // Invoked in the |caller_task_runner_| thread to report local mouse events. | 188 // Invoked in the |caller_task_runner_| thread to report local mouse events |
| 190 MouseMoveObserver* mouse_move_observer_; | 189 // and session disconnect requests. |
| 191 | 190 base::WeakPtr<ClientSessionControl> client_session_control_; |
| 192 // Posted to the |caller_task_runner_| thread every time the disconnect key | |
| 193 // combination is pressed. | |
| 194 base::Closure disconnect_callback_; | |
| 195 | 191 |
| 196 DISALLOW_COPY_AND_ASSIGN(Core); | 192 DISALLOW_COPY_AND_ASSIGN(Core); |
| 197 }; | 193 }; |
| 198 | 194 |
| 199 LocalInputMonitorMac::LocalInputMonitorMac( | 195 LocalInputMonitorMac::LocalInputMonitorMac( |
| 200 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 196 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 201 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 197 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 202 : core_(new Core(caller_task_runner, ui_task_runner)) { | 198 base::WeakPtr<ClientSessionControl> client_session_control) |
| 199 : core_(new Core(caller_task_runner, |
| 200 ui_task_runner, |
| 201 client_session_control)) { |
| 202 core_->Start(); |
| 203 } | 203 } |
| 204 | 204 |
| 205 LocalInputMonitorMac::~LocalInputMonitorMac() { | 205 LocalInputMonitorMac::~LocalInputMonitorMac() { |
| 206 } | |
| 207 | |
| 208 void LocalInputMonitorMac::Start(MouseMoveObserver* mouse_move_observer, | |
| 209 const base::Closure& disconnect_callback) { | |
| 210 core_->Start(mouse_move_observer, disconnect_callback); | |
| 211 } | |
| 212 | |
| 213 void LocalInputMonitorMac::Stop() { | |
| 214 core_->Stop(); | 206 core_->Stop(); |
| 215 } | 207 } |
| 216 | 208 |
| 217 LocalInputMonitorMac::Core::Core( | 209 LocalInputMonitorMac::Core::Core( |
| 218 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 210 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 219 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 211 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 212 base::WeakPtr<ClientSessionControl> client_session_control) |
| 220 : caller_task_runner_(caller_task_runner), | 213 : caller_task_runner_(caller_task_runner), |
| 221 ui_task_runner_(ui_task_runner), | 214 ui_task_runner_(ui_task_runner), |
| 222 manager_(nil), | 215 manager_(nil), |
| 223 mouse_move_observer_(NULL) { | 216 client_session_control_(client_session_control) { |
| 217 DCHECK(client_session_control_); |
| 224 } | 218 } |
| 225 | 219 |
| 226 void LocalInputMonitorMac::Core::Start( | 220 void LocalInputMonitorMac::Core::Start() { |
| 227 MouseMoveObserver* mouse_move_observer, | |
| 228 const base::Closure& disconnect_callback) { | |
| 229 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 221 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 230 DCHECK(disconnect_callback_.is_null()); | |
| 231 DCHECK(!disconnect_callback.is_null()); | |
| 232 DCHECK(!mouse_move_observer_); | |
| 233 DCHECK(mouse_move_observer); | |
| 234 | 222 |
| 235 disconnect_callback_ = disconnect_callback; | |
| 236 mouse_move_observer_ = mouse_move_observer; | |
| 237 ui_task_runner_->PostTask(FROM_HERE, | 223 ui_task_runner_->PostTask(FROM_HERE, |
| 238 base::Bind(&Core::StartOnUiThread, this)); | 224 base::Bind(&Core::StartOnUiThread, this)); |
| 239 } | 225 } |
| 240 | 226 |
| 241 void LocalInputMonitorMac::Core::Stop() { | 227 void LocalInputMonitorMac::Core::Stop() { |
| 242 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 228 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 243 | 229 |
| 244 mouse_move_observer_ = NULL; | |
| 245 disconnect_callback_.Reset(); | |
| 246 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this)); | 230 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this)); |
| 247 } | 231 } |
| 248 | 232 |
| 249 LocalInputMonitorMac::Core::~Core() { | 233 LocalInputMonitorMac::Core::~Core() { |
| 250 DCHECK(manager_ == nil); | 234 DCHECK(manager_ == nil); |
| 251 DCHECK(disconnect_callback_.is_null()); | |
| 252 DCHECK(!mouse_move_observer_); | |
| 253 } | 235 } |
| 254 | 236 |
| 255 void LocalInputMonitorMac::Core::StartOnUiThread() { | 237 void LocalInputMonitorMac::Core::StartOnUiThread() { |
| 256 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 238 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 257 | 239 |
| 258 manager_ = [[LocalInputMonitorManager alloc] initWithMonitor:this]; | 240 manager_ = [[LocalInputMonitorManager alloc] initWithMonitor:this]; |
| 259 } | 241 } |
| 260 | 242 |
| 261 void LocalInputMonitorMac::Core::StopOnUiThread() { | 243 void LocalInputMonitorMac::Core::StopOnUiThread() { |
| 262 DCHECK(ui_task_runner_->BelongsToCurrentThread()); | 244 DCHECK(ui_task_runner_->BelongsToCurrentThread()); |
| 263 | 245 |
| 264 [manager_ invalidate]; | 246 [manager_ invalidate]; |
| 265 [manager_ release]; | 247 [manager_ release]; |
| 266 manager_ = nil; | 248 manager_ = nil; |
| 267 } | 249 } |
| 268 | 250 |
| 269 void LocalInputMonitorMac::Core::OnLocalMouseMoved(const SkIPoint& position) { | 251 void LocalInputMonitorMac::Core::OnLocalMouseMoved(const SkIPoint& position) { |
| 270 if (!caller_task_runner_->BelongsToCurrentThread()) { | 252 caller_task_runner_->PostTask( |
| 271 caller_task_runner_->PostTask( | 253 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved, |
| 272 FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position)); | 254 client_session_control_, |
| 273 return; | 255 position)); |
| 274 } | |
| 275 | |
| 276 if (mouse_move_observer_) | |
| 277 mouse_move_observer_->OnLocalMouseMoved(position); | |
| 278 } | 256 } |
| 279 | 257 |
| 280 void LocalInputMonitorMac::Core::OnDisconnectShortcut() { | 258 void LocalInputMonitorMac::Core::OnDisconnectShortcut() { |
| 281 if (!caller_task_runner_->BelongsToCurrentThread()) { | 259 caller_task_runner_->PostTask( |
| 282 caller_task_runner_->PostTask( | 260 FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession, |
| 283 FROM_HERE, base::Bind(&Core::OnDisconnectShortcut, this)); | 261 client_session_control_)); |
| 284 return; | |
| 285 } | |
| 286 | |
| 287 if (!disconnect_callback_.is_null()) | |
| 288 disconnect_callback_.Run(); | |
| 289 } | 262 } |
| 290 | 263 |
| 291 } // namespace | 264 } // namespace |
| 292 | 265 |
| 293 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( | 266 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( |
| 294 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 267 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
| 295 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 268 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
| 296 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 269 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
| 270 base::WeakPtr<ClientSessionControl> client_session_control) { |
| 297 return scoped_ptr<LocalInputMonitor>( | 271 return scoped_ptr<LocalInputMonitor>( |
| 298 new LocalInputMonitorMac(caller_task_runner, ui_task_runner)); | 272 new LocalInputMonitorMac(caller_task_runner, |
| 273 ui_task_runner, |
| 274 client_session_control)); |
| 299 } | 275 } |
| 300 | 276 |
| 301 } // namespace remoting | 277 } // namespace remoting |
| OLD | NEW |