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"
15 // Runs an instance of |HostWindow| on the |ui_task_runner_| thread.
16 class HostWindowProxy::Core
17 : public base::RefCountedThreadSafe<Core>,
18 public ClientSessionControl {
20 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
21 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
22 scoped_ptr<HostWindow> host_window);
24 // Starts |host_window_| on the |ui_task_runner_| thread.
25 void Start(const base::WeakPtr<ClientSessionControl>& client_session_control);
27 // Destroys |host_window_| on the |ui_task_runner_| thread.
31 friend class base::RefCountedThreadSafe<Core>;
34 // Start() and Stop() equivalents called on the |ui_task_runner_| thread.
35 void StartOnUiThread(const std::string& client_jid);
36 void StopOnUiThread();
38 // ClientSessionControl interface.
39 virtual const std::string& client_jid() const OVERRIDE;
40 virtual void DisconnectSession() OVERRIDE;
41 virtual void OnLocalMouseMoved(const SkIPoint& position) OVERRIDE;
42 virtual void SetDisableInputs(bool disable_inputs) OVERRIDE;
44 // Task runner on which public methods of this class must be called.
45 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
47 // Task runner on which |host_window_| is running.
48 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
50 // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
51 std::string client_jid_;
53 // Used to notify the caller about the local user's actions on
54 // the |caller_task_runner| thread.
55 base::WeakPtr<ClientSessionControl> client_session_control_;
57 // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
58 scoped_ptr<HostWindow> host_window_;
60 // Used to create the control pointer passed to |host_window_|.
61 base::WeakPtrFactory<ClientSessionControl> weak_factory_;
63 DISALLOW_COPY_AND_ASSIGN(Core);
66 HostWindowProxy::HostWindowProxy(
67 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
68 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
69 scoped_ptr<HostWindow> host_window) {
70 DCHECK(caller_task_runner->BelongsToCurrentThread());
72 // Detach |host_window| from the calling thread so that |Core| could run it on
73 // the |ui_task_runner_| thread.
74 host_window->DetachFromThread();
75 core_ = new Core(caller_task_runner, ui_task_runner, host_window.Pass());
78 HostWindowProxy::~HostWindowProxy() {
79 DCHECK(CalledOnValidThread());
84 void HostWindowProxy::Start(
85 const base::WeakPtr<ClientSessionControl>& client_session_control) {
86 DCHECK(CalledOnValidThread());
88 core_->Start(client_session_control);
91 HostWindowProxy::Core::Core(
92 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
93 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
94 scoped_ptr<HostWindow> host_window)
95 : caller_task_runner_(caller_task_runner),
96 ui_task_runner_(ui_task_runner),
97 host_window_(host_window.Pass()),
99 DCHECK(caller_task_runner->BelongsToCurrentThread());
102 void HostWindowProxy::Core::Start(
103 const base::WeakPtr<ClientSessionControl>& client_session_control) {
104 DCHECK(caller_task_runner_->BelongsToCurrentThread());
105 DCHECK(!client_session_control_.get());
106 DCHECK(client_session_control.get());
108 client_session_control_ = client_session_control;
109 ui_task_runner_->PostTask(
110 FROM_HERE, base::Bind(&Core::StartOnUiThread, this,
111 client_session_control->client_jid()));
114 void HostWindowProxy::Core::Stop() {
115 DCHECK(caller_task_runner_->BelongsToCurrentThread());
117 ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
120 HostWindowProxy::Core::~Core() {
121 DCHECK(!host_window_);
124 void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) {
125 DCHECK(ui_task_runner_->BelongsToCurrentThread());
126 DCHECK(client_jid_.empty());
128 client_jid_ = client_jid;
129 host_window_->Start(weak_factory_.GetWeakPtr());
132 void HostWindowProxy::Core::StopOnUiThread() {
133 DCHECK(ui_task_runner_->BelongsToCurrentThread());
135 host_window_.reset();
138 const std::string& HostWindowProxy::Core::client_jid() const {
139 DCHECK(ui_task_runner_->BelongsToCurrentThread());
144 void HostWindowProxy::Core::DisconnectSession() {
145 if (!caller_task_runner_->BelongsToCurrentThread()) {
146 caller_task_runner_->PostTask(FROM_HERE,
147 base::Bind(&Core::DisconnectSession, this));
151 if (client_session_control_.get())
152 client_session_control_->DisconnectSession();
155 void HostWindowProxy::Core::OnLocalMouseMoved(const SkIPoint& position) {
156 if (!caller_task_runner_->BelongsToCurrentThread()) {
157 caller_task_runner_->PostTask(
158 FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position));
162 if (client_session_control_.get())
163 client_session_control_->OnLocalMouseMoved(position);
166 void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs) {
167 if (!caller_task_runner_->BelongsToCurrentThread()) {
168 caller_task_runner_->PostTask(
169 FROM_HERE, base::Bind(&Core::SetDisableInputs, this, disable_inputs));
173 if (client_session_control_.get())
174 client_session_control_->SetDisableInputs(disable_inputs);
177 } // namespace remoting