1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "remoting/host/mouse_cursor_monitor_proxy.h"
6 
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/macros.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
15 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
16 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
17 
18 #if defined(OS_CHROMEOS)
19 #include "remoting/host/chromeos/mouse_cursor_monitor_aura.h"
20 #endif
21 
22 namespace remoting {
23 
24 class MouseCursorMonitorProxy::Core
25     : public webrtc::MouseCursorMonitor::Callback {
26  public:
27   explicit Core(base::WeakPtr<MouseCursorMonitorProxy> proxy);
28   ~Core() override;
29 
30   void CreateMouseCursorMonitor(const webrtc::DesktopCaptureOptions& options);
31 
32   void Init(webrtc::MouseCursorMonitor::Mode mode);
33   void Capture();
34 
35   void SetMouseCursorMonitorForTests(
36       std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor);
37 
38  private:
39   // webrtc::MouseCursorMonitor::Callback implementation.
40   void OnMouseCursor(webrtc::MouseCursor* mouse_cursor) override;
41   void OnMouseCursorPosition(const webrtc::DesktopVector& position) override;
42 
43   base::ThreadChecker thread_checker_;
44 
45   base::WeakPtr<MouseCursorMonitorProxy> proxy_;
46   scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
47   std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor_;
48 
49   DISALLOW_COPY_AND_ASSIGN(Core);
50 };
51 
Core(base::WeakPtr<MouseCursorMonitorProxy> proxy)52 MouseCursorMonitorProxy::Core::Core(
53     base::WeakPtr<MouseCursorMonitorProxy> proxy)
54     : proxy_(proxy), caller_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
55   thread_checker_.DetachFromThread();
56 }
57 
~Core()58 MouseCursorMonitorProxy::Core::~Core() {
59   DCHECK(thread_checker_.CalledOnValidThread());
60 }
61 
CreateMouseCursorMonitor(const webrtc::DesktopCaptureOptions & options)62 void MouseCursorMonitorProxy::Core::CreateMouseCursorMonitor(
63     const webrtc::DesktopCaptureOptions& options) {
64   DCHECK(thread_checker_.CalledOnValidThread());
65 
66 #if defined(OS_CHROMEOS)
67   mouse_cursor_monitor_.reset(new MouseCursorMonitorAura());
68 #else   // defined(OS_CHROMEOS)
69   mouse_cursor_monitor_.reset(webrtc::MouseCursorMonitor::CreateForScreen(
70       options, webrtc::kFullDesktopScreenId));
71 #endif  // defined(OS_CHROMEOS)
72   if (!mouse_cursor_monitor_)
73     LOG(ERROR) << "Failed to initialize MouseCursorMonitor.";
74 }
75 
Init(webrtc::MouseCursorMonitor::Mode mode)76 void MouseCursorMonitorProxy::Core::Init(
77     webrtc::MouseCursorMonitor::Mode mode) {
78   DCHECK(thread_checker_.CalledOnValidThread());
79 
80   if (mouse_cursor_monitor_)
81     mouse_cursor_monitor_->Init(this, mode);
82 }
83 
Capture()84 void MouseCursorMonitorProxy::Core::Capture() {
85   DCHECK(thread_checker_.CalledOnValidThread());
86 
87   if (mouse_cursor_monitor_)
88     mouse_cursor_monitor_->Capture();
89 }
90 
SetMouseCursorMonitorForTests(std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor)91 void MouseCursorMonitorProxy::Core::SetMouseCursorMonitorForTests(
92     std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor) {
93   mouse_cursor_monitor_ = std::move(mouse_cursor_monitor);
94 }
95 
OnMouseCursor(webrtc::MouseCursor * cursor)96 void MouseCursorMonitorProxy::Core::OnMouseCursor(webrtc::MouseCursor* cursor) {
97   DCHECK(thread_checker_.CalledOnValidThread());
98 
99   std::unique_ptr<webrtc::MouseCursor> owned_cursor(cursor);
100   caller_task_runner_->PostTask(
101       FROM_HERE, base::BindOnce(&MouseCursorMonitorProxy::OnMouseCursor, proxy_,
102                                 std::move(owned_cursor)));
103 }
104 
OnMouseCursorPosition(const webrtc::DesktopVector & position)105 void MouseCursorMonitorProxy::Core::OnMouseCursorPosition(
106     const webrtc::DesktopVector& position) {
107   DCHECK(thread_checker_.CalledOnValidThread());
108 
109   caller_task_runner_->PostTask(
110       FROM_HERE, base::BindOnce(&MouseCursorMonitorProxy::OnMouseCursorPosition,
111                                 proxy_, position));
112 }
113 
MouseCursorMonitorProxy(scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,const webrtc::DesktopCaptureOptions & options)114 MouseCursorMonitorProxy::MouseCursorMonitorProxy(
115     scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
116     const webrtc::DesktopCaptureOptions& options)
117     : capture_task_runner_(capture_task_runner) {
118   core_.reset(new Core(weak_factory_.GetWeakPtr()));
119   capture_task_runner_->PostTask(
120       FROM_HERE, base::BindOnce(&Core::CreateMouseCursorMonitor,
121                                 base::Unretained(core_.get()), options));
122 }
123 
~MouseCursorMonitorProxy()124 MouseCursorMonitorProxy::~MouseCursorMonitorProxy() {
125   capture_task_runner_->DeleteSoon(FROM_HERE, core_.release());
126 }
127 
Init(Callback * callback,Mode mode)128 void MouseCursorMonitorProxy::Init(Callback* callback, Mode mode) {
129   DCHECK(thread_checker_.CalledOnValidThread());
130   callback_ = callback;
131   capture_task_runner_->PostTask(
132       FROM_HERE,
133       base::BindOnce(&Core::Init, base::Unretained(core_.get()), mode));
134 }
135 
Capture()136 void MouseCursorMonitorProxy::Capture() {
137   DCHECK(thread_checker_.CalledOnValidThread());
138   capture_task_runner_->PostTask(
139       FROM_HERE, base::BindOnce(&Core::Capture, base::Unretained(core_.get())));
140 }
141 
SetMouseCursorMonitorForTests(std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor)142 void MouseCursorMonitorProxy::SetMouseCursorMonitorForTests(
143     std::unique_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor) {
144   capture_task_runner_->PostTask(
145       FROM_HERE, base::BindOnce(&Core::SetMouseCursorMonitorForTests,
146                                 base::Unretained(core_.get()),
147                                 std::move(mouse_cursor_monitor)));
148 }
149 
OnMouseCursor(std::unique_ptr<webrtc::MouseCursor> cursor)150 void MouseCursorMonitorProxy::OnMouseCursor(
151     std::unique_ptr<webrtc::MouseCursor> cursor) {
152   DCHECK(thread_checker_.CalledOnValidThread());
153   callback_->OnMouseCursor(cursor.release());
154 }
155 
OnMouseCursorPosition(const webrtc::DesktopVector & position)156 void MouseCursorMonitorProxy::OnMouseCursorPosition(
157     const webrtc::DesktopVector& position) {
158   DCHECK(thread_checker_.CalledOnValidThread());
159   callback_->OnMouseCursorPosition(position);
160 }
161 
162 }  // namespace remoting
163