- add sources.
[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
13 namespace remoting {
14
15 // Runs an instance of |HostWindow| on the |ui_task_runner_| thread.
16 class HostWindowProxy::Core
17     : public base::RefCountedThreadSafe<Core>,
18       public ClientSessionControl {
19  public:
20   Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
21        scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
22        scoped_ptr<HostWindow> host_window);
23
24   // Starts |host_window_| on the |ui_task_runner_| thread.
25   void Start(const base::WeakPtr<ClientSessionControl>& client_session_control);
26
27   // Destroys |host_window_| on the |ui_task_runner_| thread.
28   void Stop();
29
30  private:
31   friend class base::RefCountedThreadSafe<Core>;
32   virtual ~Core();
33
34   // Start() and Stop() equivalents called on the |ui_task_runner_| thread.
35   void StartOnUiThread(const std::string& client_jid);
36   void StopOnUiThread();
37
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;
43
44   // Task runner on which public methods of this class must be called.
45   scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
46
47   // Task runner on which |host_window_| is running.
48   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
49
50   // Stores the client's JID so it can be read on the |ui_task_runner_| thread.
51   std::string client_jid_;
52
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_;
56
57   // The wrapped |HostWindow| instance running on the |ui_task_runner_| thread.
58   scoped_ptr<HostWindow> host_window_;
59
60   // Used to create the control pointer passed to |host_window_|.
61   base::WeakPtrFactory<ClientSessionControl> weak_factory_;
62
63   DISALLOW_COPY_AND_ASSIGN(Core);
64 };
65
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());
71
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());
76 }
77
78 HostWindowProxy::~HostWindowProxy() {
79   DCHECK(CalledOnValidThread());
80
81   core_->Stop();
82 }
83
84 void HostWindowProxy::Start(
85     const base::WeakPtr<ClientSessionControl>& client_session_control) {
86   DCHECK(CalledOnValidThread());
87
88   core_->Start(client_session_control);
89 }
90
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()),
98       weak_factory_(this) {
99   DCHECK(caller_task_runner->BelongsToCurrentThread());
100 }
101
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());
107
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()));
112 }
113
114 void HostWindowProxy::Core::Stop() {
115   DCHECK(caller_task_runner_->BelongsToCurrentThread());
116
117   ui_task_runner_->PostTask(FROM_HERE, base::Bind(&Core::StopOnUiThread, this));
118 }
119
120 HostWindowProxy::Core::~Core() {
121   DCHECK(!host_window_);
122 }
123
124 void HostWindowProxy::Core::StartOnUiThread(const std::string& client_jid) {
125   DCHECK(ui_task_runner_->BelongsToCurrentThread());
126   DCHECK(client_jid_.empty());
127
128   client_jid_ = client_jid;
129   host_window_->Start(weak_factory_.GetWeakPtr());
130 }
131
132 void HostWindowProxy::Core::StopOnUiThread() {
133   DCHECK(ui_task_runner_->BelongsToCurrentThread());
134
135   host_window_.reset();
136 }
137
138 const std::string& HostWindowProxy::Core::client_jid() const {
139   DCHECK(ui_task_runner_->BelongsToCurrentThread());
140
141   return client_jid_;
142 }
143
144 void HostWindowProxy::Core::DisconnectSession() {
145   if (!caller_task_runner_->BelongsToCurrentThread()) {
146     caller_task_runner_->PostTask(FROM_HERE,
147                                   base::Bind(&Core::DisconnectSession, this));
148     return;
149   }
150
151   if (client_session_control_.get())
152     client_session_control_->DisconnectSession();
153 }
154
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));
159     return;
160   }
161
162   if (client_session_control_.get())
163     client_session_control_->OnLocalMouseMoved(position);
164 }
165
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));
170     return;
171   }
172
173   if (client_session_control_.get())
174     client_session_control_->SetDisableInputs(disable_inputs);
175 }
176
177 }  // namespace remoting