Upstream version 10.39.233.0
[platform/framework/web/crosswalk.git] / src / remoting / host / host_window_proxy.cc
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   virtual void ResetVideoPipeline() OVERRIDE;
46
47   // Task runner on which public methods of this class must be called.
48   scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
49
50   // Task runner on which |host_window_| is running.
51   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
52
53   // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
54   std::string client_jid_;
55
56   // Used to notify the caller about the local user's actions on
57   // the |caller_task_runner| thread.
58   base::WeakPtr<ClientSessionControl> client_session_control_;
59
60   // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
61   scoped_ptr<HostWindow> host_window_;
62
63   // Used to create the control pointer passed to |host_window_|.
64   base::WeakPtrFactory<ClientSessionControl> weak_factory_;
65
66   DISALLOW_COPY_AND_ASSIGN(Core);
67 };
68
69 HostWindowProxy::HostWindowProxy(
70     scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
71     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
72     scoped_ptr<HostWindow> host_window) {
73   DCHECK(caller_task_runner->BelongsToCurrentThread());
74
75   // Detach |host_window| from the calling thread so that |Core| could run it on
76   // the |ui_task_runner_| thread.
77   host_window->DetachFromThread();
78   core_ = new Core(caller_task_runner, ui_task_runner, host_window.Pass());
79 }
80
81 HostWindowProxy::~HostWindowProxy() {
82   DCHECK(CalledOnValidThread());
83
84   core_->Stop();
85 }
86
87 void HostWindowProxy::Start(
88     const base::WeakPtr<ClientSessionControl>& client_session_control) {
89   DCHECK(CalledOnValidThread());
90
91   core_->Start(client_session_control);
92 }
93
94 HostWindowProxy::Core::Core(
95     scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
96     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
97     scoped_ptr<HostWindow> host_window)
98     : caller_task_runner_(caller_task_runner),
99       ui_task_runner_(ui_task_runner),
100       host_window_(host_window.Pass()),
101       weak_factory_(this) {
102   DCHECK(caller_task_runner->BelongsToCurrentThread());
103 }
104
105 void HostWindowProxy::Core::Start(
106     const base::WeakPtr<ClientSessionControl>& client_session_control) {
107   DCHECK(caller_task_runner_->BelongsToCurrentThread());
108   DCHECK(!client_session_control_.get());
109   DCHECK(client_session_control.get());
110
111   client_session_control_ = client_session_control;
112   ui_task_runner_->PostTask(
113       FROM_HERE, base::Bind(&Core::StartOnUiThread, this,
114                             client_session_control->client_jid()));
115 }
116
117 void HostWindowProxy::Core::Stop() {
118   DCHECK(caller_task_runner_->BelongsToCurrentThread());
119
120   ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
121 }
122
123 HostWindowProxy::Core::~Core() {
124   DCHECK(!host_window_);
125 }
126
127 void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) {
128   DCHECK(ui_task_runner_->BelongsToCurrentThread());
129   DCHECK(client_jid_.empty());
130
131   client_jid_ = client_jid;
132   host_window_->Start(weak_factory_.GetWeakPtr());
133 }
134
135 void HostWindowProxy::Core::StopOnUiThread() {
136   DCHECK(ui_task_runner_->BelongsToCurrentThread());
137
138   host_window_.reset();
139 }
140
141 const std::string& HostWindowProxy::Core::client_jid() const {
142   DCHECK(ui_task_runner_->BelongsToCurrentThread());
143
144   return client_jid_;
145 }
146
147 void HostWindowProxy::Core::DisconnectSession() {
148   if (!caller_task_runner_->BelongsToCurrentThread()) {
149     caller_task_runner_->PostTask(FROM_HERE,
150                                   base::Bind(&Core::DisconnectSession, this));
151     return;
152   }
153
154   if (client_session_control_.get())
155     client_session_control_->DisconnectSession();
156 }
157
158 void HostWindowProxy::Core::OnLocalMouseMoved(
159     const webrtc::DesktopVector& position) {
160   if (!caller_task_runner_->BelongsToCurrentThread()) {
161     caller_task_runner_->PostTask(
162         FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position));
163     return;
164   }
165
166   if (client_session_control_.get())
167     client_session_control_->OnLocalMouseMoved(position);
168 }
169
170 void HostWindowProxy::Core::SetDisableInputs(bool disable_inputs) {
171   if (!caller_task_runner_->BelongsToCurrentThread()) {
172     caller_task_runner_->PostTask(
173         FROM_HERE, base::Bind(&Core::SetDisableInputs, this, disable_inputs));
174     return;
175   }
176
177   if (client_session_control_.get())
178     client_session_control_->SetDisableInputs(disable_inputs);
179 }
180
181 void HostWindowProxy::Core::ResetVideoPipeline() {
182   // ResetVideoPipeline is only used by HostExtensionSession implementations.
183   NOTREACHED();
184 }
185
186 }  // namespace remoting