1 // Copyright 2013 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.
5 #include "remoting/host/host_window_proxy.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "remoting/host/client_session_control.h"
12 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
16 // Runs an instance of |HostWindow| on the |ui_task_runner_| thread.
17 class HostWindowProxy::Core
18 : public base::RefCountedThreadSafe
<Core
>,
19 public ClientSessionControl
{
21 Core(scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
22 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner
,
23 scoped_ptr
<HostWindow
> host_window
);
25 // Starts |host_window_| on the |ui_task_runner_| thread.
26 void Start(const base::WeakPtr
<ClientSessionControl
>& client_session_control
);
28 // Destroys |host_window_| on the |ui_task_runner_| thread.
32 friend class base::RefCountedThreadSafe
<Core
>;
35 // Start() and Stop() equivalents called on the |ui_task_runner_| thread.
36 void StartOnUiThread(const std::string
& client_jid
);
37 void StopOnUiThread();
39 // ClientSessionControl interface.
40 virtual const std::string
& client_jid() const OVERRIDE
;
41 virtual void DisconnectSession() OVERRIDE
;
42 virtual void OnLocalMouseMoved(
43 const webrtc::DesktopVector
& position
) OVERRIDE
;
44 virtual void SetDisableInputs(bool disable_inputs
) OVERRIDE
;
46 // Task runner on which public methods of this class must be called.
47 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner_
;
49 // Task runner on which |host_window_| is running.
50 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner_
;
52 // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
53 std::string client_jid_
;
55 // Used to notify the caller about the local user's actions on
56 // the |caller_task_runner| thread.
57 base::WeakPtr
<ClientSessionControl
> client_session_control_
;
59 // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
60 scoped_ptr
<HostWindow
> host_window_
;
62 // Used to create the control pointer passed to |host_window_|.
63 base::WeakPtrFactory
<ClientSessionControl
> weak_factory_
;
65 DISALLOW_COPY_AND_ASSIGN(Core
);
68 HostWindowProxy::HostWindowProxy(
69 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
70 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner
,
71 scoped_ptr
<HostWindow
> host_window
) {
72 DCHECK(caller_task_runner
->BelongsToCurrentThread());
74 // Detach |host_window| from the calling thread so that |Core| could run it on
75 // the |ui_task_runner_| thread.
76 host_window
->DetachFromThread();
77 core_
= new Core(caller_task_runner
, ui_task_runner
, host_window
.Pass());
80 HostWindowProxy::~HostWindowProxy() {
81 DCHECK(CalledOnValidThread());
86 void HostWindowProxy::Start(
87 const base::WeakPtr
<ClientSessionControl
>& client_session_control
) {
88 DCHECK(CalledOnValidThread());
90 core_
->Start(client_session_control
);
93 HostWindowProxy::Core::Core(
94 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
95 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner
,
96 scoped_ptr
<HostWindow
> host_window
)
97 : caller_task_runner_(caller_task_runner
),
98 ui_task_runner_(ui_task_runner
),
99 host_window_(host_window
.Pass()),
100 weak_factory_(this) {
101 DCHECK(caller_task_runner
->BelongsToCurrentThread());
104 void HostWindowProxy::Core::Start(
105 const base::WeakPtr
<ClientSessionControl
>& client_session_control
) {
106 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
107 DCHECK(!client_session_control_
.get());
108 DCHECK(client_session_control
.get());
110 client_session_control_
= client_session_control
;
111 ui_task_runner_
->PostTask(
112 FROM_HERE
, base::Bind(&Core::StartOnUiThread
, this,
113 client_session_control
->client_jid()));
116 void HostWindowProxy::Core::Stop() {
117 DCHECK(caller_task_runner_
->BelongsToCurrentThread());
119 ui_task_runner_
->PostTask(FROM_HERE
, base::Bind(&Core::StopOnUiThread
, this));
122 HostWindowProxy::Core::~Core() {
123 DCHECK(!host_window_
);
126 void HostWindowProxy::Core::StartOnUiThread(const std::string
& client_jid
) {
127 DCHECK(ui_task_runner_
->BelongsToCurrentThread());
128 DCHECK(client_jid_
.empty());
130 client_jid_
= client_jid
;
131 host_window_
->Start(weak_factory_
.GetWeakPtr());
134 void HostWindowProxy::Core::StopOnUiThread() {
135 DCHECK(ui_task_runner_
->BelongsToCurrentThread());
137 host_window_
.reset();
140 const std::string
& HostWindowProxy::Core::client_jid() const {
141 DCHECK(ui_task_runner_
->BelongsToCurrentThread());
146 void HostWindowProxy::Core::DisconnectSession() {
147 if (!caller_task_runner_
->BelongsToCurrentThread()) {
148 caller_task_runner_
->PostTask(FROM_HERE
,
149 base::Bind(&Core::DisconnectSession
, this));
153 if (client_session_control_
.get())
154 client_session_control_
->DisconnectSession();
157 void HostWindowProxy::Core::OnLocalMouseMoved(
158 const webrtc::DesktopVector
& position
) {
159 if (!caller_task_runner_
->BelongsToCurrentThread()) {
160 caller_task_runner_
->PostTask(
161 FROM_HERE
, base::Bind(&Core::OnLocalMouseMoved
, this, position
));
165 if (client_session_control_
.get())
166 client_session_control_
->OnLocalMouseMoved(position
);
169 void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs
) {
170 if (!caller_task_runner_
->BelongsToCurrentThread()) {
171 caller_task_runner_
->PostTask(
172 FROM_HERE
, base::Bind(&Core::SetDisableInputs
, this, disable_inputs
));
176 if (client_session_control_
.get())
177 client_session_control_
->SetDisableInputs(disable_inputs
);
180 } // namespace remoting