1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/host_window_proxy.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/single_thread_task_runner.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/host/client_session_control.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace remoting {
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Runs an instance of |HostWindow| on the |ui_task_runner_| thread.
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class HostWindowProxy::Core
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public base::RefCountedThreadSafe<Core>,
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      public ClientSessionControl {
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       scoped_ptr<HostWindow> host_window);
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Starts |host_window_| on the |ui_task_runner_| thread.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Start(const base::WeakPtr<ClientSessionControl>& client_session_control);
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Destroys |host_window_| on the |ui_task_runner_| thread.
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Stop();
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class base::RefCountedThreadSafe<Core>;
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~Core();
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start() and Stop() equivalents called on the |ui_task_runner_| thread.
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartOnUiThread(const std::string& client_jid);
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StopOnUiThread();
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ClientSessionControl interface.
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual const std::string& client_jid() const OVERRIDE;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DisconnectSession() OVERRIDE;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnLocalMouseMoved(
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const webrtc::DesktopVector& position) OVERRIDE;
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetDisableInputs(bool disable_inputs) OVERRIDE;
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Task runner on which public methods of this class must be called.
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Task runner on which |host_window_| is running.
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string client_jid_;
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Used to notify the caller about the local user's actions on
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the |caller_task_runner| thread.
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WeakPtr<ClientSessionControl> client_session_control_;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<HostWindow> host_window_;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Used to create the control pointer passed to |host_window_|.
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WeakPtrFactory<ClientSessionControl> weak_factory_;
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Core);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::HostWindowProxy(
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<HostWindow> host_window) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(caller_task_runner->BelongsToCurrentThread());
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Detach |host_window| from the calling thread so that |Core| could run it on
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the |ui_task_runner_| thread.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_window->DetachFromThread();
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  core_ = new Core(caller_task_runner, ui_task_runner, host_window.Pass());
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::~HostWindowProxy() {
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(CalledOnValidThread());
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  core_->Stop();
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Start(
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::WeakPtr<ClientSessionControl>& client_session_control) {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(CalledOnValidThread());
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  core_->Start(client_session_control);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::Core::Core(
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_ptr<HostWindow> host_window)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : caller_task_runner_(caller_task_runner),
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui_task_runner_(ui_task_runner),
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_window_(host_window.Pass()),
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(caller_task_runner->BelongsToCurrentThread());
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::Start(
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::WeakPtr<ClientSessionControl>& client_session_control) {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(caller_task_runner_->BelongsToCurrentThread());
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!client_session_control_.get());
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(client_session_control.get());
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client_session_control_ = client_session_control;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui_task_runner_->PostTask(
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE, base::Bind(&Core::StartOnUiThread, this,
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            client_session_control->client_jid()));
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::Stop() {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(caller_task_runner_->BelongsToCurrentThread());
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostWindowProxy::Core::~Core() {
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!host_window_);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) {
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(ui_task_runner_->BelongsToCurrentThread());
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(client_jid_.empty());
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client_jid_ = client_jid;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_window_->Start(weak_factory_.GetWeakPtr());
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::StopOnUiThread() {
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(ui_task_runner_->BelongsToCurrentThread());
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_window_.reset();
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& HostWindowProxy::Core::client_jid() const {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(ui_task_runner_->BelongsToCurrentThread());
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return client_jid_;
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::DisconnectSession() {
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!caller_task_runner_->BelongsToCurrentThread()) {
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    caller_task_runner_->PostTask(FROM_HERE,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  base::Bind(&Core::DisconnectSession, this));
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (client_session_control_.get())
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client_session_control_->DisconnectSession();
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void HostWindowProxy::Core::OnLocalMouseMoved(
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const webrtc::DesktopVector& position) {
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!caller_task_runner_->BelongsToCurrentThread()) {
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    caller_task_runner_->PostTask(
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position));
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (client_session_control_.get())
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client_session_control_->OnLocalMouseMoved(position);
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs) {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!caller_task_runner_->BelongsToCurrentThread()) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    caller_task_runner_->PostTask(
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        FROM_HERE, base::Bind(&Core::SetDisableInputs, this, disable_inputs));
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (client_session_control_.get())
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    client_session_control_->SetDisableInputs(disable_inputs);
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace remoting
181