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