• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "remoting/host/host_window_proxy.h"
6 
7 #include "base/bind.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"
13 
14 namespace remoting {
15 
16 // Runs an instance of |HostWindow| on the |ui_task_runner_| thread.
17 class HostWindowProxy::Core
18     : public base::RefCountedThreadSafe<Core>,
19       public ClientSessionControl {
20  public:
21   Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
22        scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
23        scoped_ptr<HostWindow> host_window);
24 
25   // Starts |host_window_| on the |ui_task_runner_| thread.
26   void Start(const base::WeakPtr<ClientSessionControl>& client_session_control);
27 
28   // Destroys |host_window_| on the |ui_task_runner_| thread.
29   void Stop();
30 
31  private:
32   friend class base::RefCountedThreadSafe<Core>;
33   virtual ~Core();
34 
35   // Start() and Stop() equivalents called on the |ui_task_runner_| thread.
36   void StartOnUiThread(const std::string& client_jid);
37   void StopOnUiThread();
38 
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;
45 
46   // Task runner on which public methods of this class must be called.
47   scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
48 
49   // Task runner on which |host_window_| is running.
50   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
51 
52   // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
53   std::string client_jid_;
54 
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_;
58 
59   // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
60   scoped_ptr<HostWindow> host_window_;
61 
62   // Used to create the control pointer passed to |host_window_|.
63   base::WeakPtrFactory<ClientSessionControl> weak_factory_;
64 
65   DISALLOW_COPY_AND_ASSIGN(Core);
66 };
67 
HostWindowProxy(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,scoped_ptr<HostWindow> host_window)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());
73 
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());
78 }
79 
~HostWindowProxy()80 HostWindowProxy::~HostWindowProxy() {
81   DCHECK(CalledOnValidThread());
82 
83   core_->Stop();
84 }
85 
Start(const base::WeakPtr<ClientSessionControl> & client_session_control)86 void HostWindowProxy::Start(
87     const base::WeakPtr<ClientSessionControl>& client_session_control) {
88   DCHECK(CalledOnValidThread());
89 
90   core_->Start(client_session_control);
91 }
92 
Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,scoped_ptr<HostWindow> host_window)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());
102 }
103 
Start(const base::WeakPtr<ClientSessionControl> & client_session_control)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());
109 
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()));
114 }
115 
Stop()116 void HostWindowProxy::Core::Stop() {
117   DCHECK(caller_task_runner_->BelongsToCurrentThread());
118 
119   ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
120 }
121 
~Core()122 HostWindowProxy::Core::~Core() {
123   DCHECK(!host_window_);
124 }
125 
StartOnUiThread(const std::string & client_jid)126 void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) {
127   DCHECK(ui_task_runner_->BelongsToCurrentThread());
128   DCHECK(client_jid_.empty());
129 
130   client_jid_ = client_jid;
131   host_window_->Start(weak_factory_.GetWeakPtr());
132 }
133 
StopOnUiThread()134 void HostWindowProxy::Core::StopOnUiThread() {
135   DCHECK(ui_task_runner_->BelongsToCurrentThread());
136 
137   host_window_.reset();
138 }
139 
client_jid() const140 const std::string& HostWindowProxy::Core::client_jid() const {
141   DCHECK(ui_task_runner_->BelongsToCurrentThread());
142 
143   return client_jid_;
144 }
145 
DisconnectSession()146 void HostWindowProxy::Core::DisconnectSession() {
147   if (!caller_task_runner_->BelongsToCurrentThread()) {
148     caller_task_runner_->PostTask(FROM_HERE,
149                                   base::Bind(&Core::DisconnectSession, this));
150     return;
151   }
152 
153   if (client_session_control_.get())
154     client_session_control_->DisconnectSession();
155 }
156 
OnLocalMouseMoved(const webrtc::DesktopVector & position)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));
162     return;
163   }
164 
165   if (client_session_control_.get())
166     client_session_control_->OnLocalMouseMoved(position);
167 }
168 
SetDisableInputs(bool disable_inputs)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));
173     return;
174   }
175 
176   if (client_session_control_.get())
177     client_session_control_->SetDisableInputs(disable_inputs);
178 }
179 
180 }  // namespace remoting
181