OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/desktop_environment.h" | 5 #include "remoting/host/desktop_environment.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "remoting/host/capturer.h" | 9 #include "remoting/host/capturer.h" |
10 #include "remoting/host/chromoting_host.h" | 10 #include "remoting/host/chromoting_host.h" |
11 #include "remoting/host/chromoting_host_context.h" | 11 #include "remoting/host/chromoting_host_context.h" |
12 #include "remoting/host/continue_window.h" | |
13 #include "remoting/host/curtain.h" | 12 #include "remoting/host/curtain.h" |
14 #include "remoting/host/disconnect_window.h" | |
15 #include "remoting/host/event_executor.h" | 13 #include "remoting/host/event_executor.h" |
16 #include "remoting/host/local_input_monitor.h" | |
17 | |
18 // Milliseconds before the continue window is shown. | |
19 static const int kContinueWindowShowTimeoutMs = 10 * 60 * 1000; | |
20 | |
21 // Milliseconds before the continue window is automatically dismissed and | |
22 // the connection is closed. | |
23 static const int kContinueWindowHideTimeoutMs = 60 * 1000; | |
24 | 14 |
25 namespace remoting { | 15 namespace remoting { |
26 | 16 |
27 class DesktopEnvironment::TimerTask { | |
28 public: | |
29 TimerTask(base::MessageLoopProxy* message_loop, | |
30 const base::Closure& task, | |
31 int delay_ms) | |
32 : thread_proxy_(message_loop) { | |
33 thread_proxy_.PostDelayedTask(FROM_HERE, task, delay_ms); | |
34 } | |
35 | |
36 private: | |
37 ScopedThreadProxy thread_proxy_; | |
38 }; | |
39 | |
40 // static | 17 // static |
41 DesktopEnvironment* DesktopEnvironment::Create(ChromotingHostContext* context) { | 18 DesktopEnvironment* DesktopEnvironment::Create(ChromotingHostContext* context) { |
42 scoped_ptr<Capturer> capturer(Capturer::Create()); | 19 scoped_ptr<Capturer> capturer(Capturer::Create()); |
43 scoped_ptr<EventExecutor> event_executor( | 20 scoped_ptr<EventExecutor> event_executor( |
44 EventExecutor::Create(context->desktop_message_loop(), capturer.get())); | 21 EventExecutor::Create(context->desktop_message_loop(), capturer.get())); |
45 scoped_ptr<Curtain> curtain(Curtain::Create()); | 22 scoped_ptr<Curtain> curtain(Curtain::Create()); |
46 scoped_ptr<DisconnectWindow> disconnect_window(DisconnectWindow::Create()); | |
47 scoped_ptr<ContinueWindow> continue_window(ContinueWindow::Create()); | |
48 scoped_ptr<LocalInputMonitor> local_input_monitor( | |
49 LocalInputMonitor::Create()); | |
50 | 23 |
51 if (capturer.get() == NULL || event_executor.get() == NULL || | 24 if (capturer.get() == NULL || event_executor.get() == NULL || |
52 curtain.get() == NULL || disconnect_window.get() == NULL || | 25 curtain.get() == NULL) { |
53 continue_window.get() == NULL || local_input_monitor.get() == NULL) { | |
54 LOG(ERROR) << "Unable to create DesktopEnvironment"; | 26 LOG(ERROR) << "Unable to create DesktopEnvironment"; |
55 return NULL; | 27 return NULL; |
56 } | 28 } |
57 | 29 |
58 return new DesktopEnvironment(context, | 30 return new DesktopEnvironment(context, |
59 capturer.release(), | 31 capturer.release(), |
60 event_executor.release(), | 32 event_executor.release(), |
61 curtain.release(), | 33 curtain.release()); |
62 disconnect_window.release(), | |
63 continue_window.release(), | |
64 local_input_monitor.release()); | |
65 } | 34 } |
66 | 35 |
67 DesktopEnvironment::DesktopEnvironment(ChromotingHostContext* context, | 36 DesktopEnvironment::DesktopEnvironment(ChromotingHostContext* context, |
68 Capturer* capturer, | 37 Capturer* capturer, |
69 EventExecutor* event_executor, | 38 EventExecutor* event_executor, |
70 Curtain* curtain, | 39 Curtain* curtain) |
71 DisconnectWindow* disconnect_window, | |
72 ContinueWindow* continue_window, | |
73 LocalInputMonitor* local_input_monitor) | |
74 : host_(NULL), | 40 : host_(NULL), |
75 context_(context), | 41 context_(context), |
76 capturer_(capturer), | 42 capturer_(capturer), |
77 event_executor_(event_executor), | 43 event_executor_(event_executor), |
78 curtain_(curtain), | 44 curtain_(curtain) { |
79 disconnect_window_(disconnect_window), | |
80 continue_window_(continue_window), | |
81 local_input_monitor_(local_input_monitor), | |
82 is_monitoring_local_inputs_(false), | |
83 ui_thread_proxy_(context->ui_message_loop()) { | |
84 } | 45 } |
85 | 46 |
86 DesktopEnvironment::~DesktopEnvironment() { | 47 DesktopEnvironment::~DesktopEnvironment() { |
87 } | 48 } |
88 | 49 |
89 void DesktopEnvironment::Shutdown() { | |
90 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
91 | |
92 MonitorLocalInputs(false); | |
93 ShowDisconnectWindow(false, std::string()); | |
94 ShowContinueWindow(false); | |
95 StartContinueWindowTimer(false); | |
96 | |
97 ui_thread_proxy_.Detach(); | |
98 } | |
99 | |
100 void DesktopEnvironment::OnConnect(const std::string& username) { | |
101 ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( | |
102 &DesktopEnvironment::ProcessOnConnect, base::Unretained(this), username)); | |
103 } | |
104 | |
105 void DesktopEnvironment::OnLastDisconnect() { | |
106 ui_thread_proxy_.PostTask(FROM_HERE, base::Bind( | |
107 &DesktopEnvironment::ProcessOnLastDisconnect, base::Unretained(this))); | |
108 } | |
109 | |
110 void DesktopEnvironment::OnPause(bool pause) { | |
111 } | |
112 | |
113 void DesktopEnvironment::ProcessOnConnect(const std::string& username) { | |
114 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
115 | |
116 MonitorLocalInputs(true); | |
117 ShowDisconnectWindow(true, username); | |
118 StartContinueWindowTimer(true); | |
119 } | |
120 | |
121 void DesktopEnvironment::ProcessOnLastDisconnect() { | |
122 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
123 | |
124 MonitorLocalInputs(false); | |
125 ShowDisconnectWindow(false, std::string()); | |
126 ShowContinueWindow(false); | |
127 StartContinueWindowTimer(false); | |
128 } | |
129 | |
130 void DesktopEnvironment::MonitorLocalInputs(bool enable) { | |
131 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
132 | |
133 if (enable == is_monitoring_local_inputs_) | |
134 return; | |
135 if (enable) { | |
136 local_input_monitor_->Start(host_); | |
137 } else { | |
138 local_input_monitor_->Stop(); | |
139 } | |
140 is_monitoring_local_inputs_ = enable; | |
141 } | |
142 | |
143 void DesktopEnvironment::ShowDisconnectWindow(bool show, | |
144 const std::string& username) { | |
145 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
146 | |
147 if (show) { | |
148 disconnect_window_->Show(host_, username); | |
149 } else { | |
150 disconnect_window_->Hide(); | |
151 } | |
152 } | |
153 | |
154 void DesktopEnvironment::ShowContinueWindow(bool show) { | |
155 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
156 | |
157 if (show) { | |
158 continue_window_->Show(host_, base::Bind( | |
159 &DesktopEnvironment::ContinueSession, base::Unretained(this))); | |
160 } else { | |
161 continue_window_->Hide(); | |
162 } | |
163 } | |
164 | |
165 void DesktopEnvironment::ContinueSession(bool continue_session) { | |
166 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
167 | |
168 if (continue_session) { | |
169 host_->PauseSession(false); | |
170 timer_task_.reset(); | |
171 StartContinueWindowTimer(true); | |
172 } else { | |
173 host_->Shutdown(base::Closure()); | |
174 } | |
175 } | |
176 | |
177 void DesktopEnvironment::StartContinueWindowTimer(bool start) { | |
178 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
179 | |
180 if (start) { | |
181 timer_task_.reset(new TimerTask( | |
182 context_->ui_message_loop(), | |
183 base::Bind(&DesktopEnvironment::OnContinueWindowTimer, | |
184 base::Unretained(this)), | |
185 kContinueWindowShowTimeoutMs)); | |
186 } else if (!start) { | |
187 timer_task_.reset(); | |
188 } | |
189 | |
190 } | |
191 | |
192 void DesktopEnvironment::OnContinueWindowTimer() { | |
193 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
194 | |
195 host_->PauseSession(true); | |
196 ShowContinueWindow(true); | |
197 | |
198 timer_task_.reset(new TimerTask( | |
199 context_->ui_message_loop(), | |
200 base::Bind(&DesktopEnvironment::OnShutdownHostTimer, | |
201 base::Unretained(this)), | |
202 kContinueWindowHideTimeoutMs)); | |
203 } | |
204 | |
205 void DesktopEnvironment::OnShutdownHostTimer() { | |
206 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); | |
207 | |
208 ShowContinueWindow(false); | |
209 host_->Shutdown(base::Closure()); | |
210 } | |
211 | |
212 } // namespace remoting | 50 } // namespace remoting |
OLD | NEW |