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" | 12 #include "remoting/host/continue_window.h" |
13 #include "remoting/host/curtain.h" | 13 #include "remoting/host/curtain.h" |
14 #include "remoting/host/disconnect_window.h" | 14 #include "remoting/host/disconnect_window.h" |
15 #include "remoting/host/event_executor.h" | 15 #include "remoting/host/event_executor.h" |
16 #include "remoting/host/local_input_monitor.h" | 16 #include "remoting/host/local_input_monitor.h" |
17 | 17 |
18 static const int kContinueWindowTimeoutMs = 10 * 60 * 1000; | 18 static const int kContinueWindowTimeoutMs = 10 * 60 * 1000; |
19 | 19 |
20 namespace remoting { | 20 namespace remoting { |
21 | 21 |
22 // UIThreadProxy proxies DesktopEnvironment method calls to the UI | 22 // UIThreadProxy proxies DesktopEnvironment method calls to the UI |
23 // thread. This is neccessary so that DesktopEnvironment can be | 23 // thread. This is neccessary so that DesktopEnvironment can be |
24 // deleted synchronously even while there are pending tasks on the | 24 // deleted synchronously even while there are pending tasks on the |
25 // message queue. | 25 // message queue. |
26 class UIThreadProxy : public base::RefCountedThreadSafe<UIThreadProxy> { | 26 class UIThreadProxy : public base::RefCountedThreadSafe<UIThreadProxy> { |
27 public: | 27 public: |
28 UIThreadProxy(ChromotingHostContext* context) | 28 UIThreadProxy(base::MessageLoopProxy* message_loop) |
29 : context_(context) { | 29 : message_loop_(message_loop) { |
30 } | 30 } |
31 | 31 |
32 void Detach() { | 32 void Detach() { |
33 DCHECK(context_->IsUIThread()); | 33 DCHECK(message_loop_->BelongsToCurrentThread()); |
34 context_ = NULL; | 34 message_loop_ = NULL; |
35 } | 35 } |
36 | 36 |
37 void CallOnUIThread(const tracked_objects::Location& from_here, | 37 void CallOnUIThread(const tracked_objects::Location& from_here, |
38 const base::Closure& closure) { | 38 const base::Closure& closure) { |
39 if (context_) { | 39 scoped_refptr<base::MessageLoopProxy> message_loop = message_loop_; |
40 context_->PostTaskToUIThread(from_here, base::Bind( | 40 if (message_loop) { |
| 41 message_loop->PostTask(from_here, base::Bind( |
41 &UIThreadProxy::CallClosure, this, closure)); | 42 &UIThreadProxy::CallClosure, this, closure)); |
42 } | 43 } |
43 } | 44 } |
44 | 45 |
45 void CallOnUIThreadDelayed(const tracked_objects::Location& from_here, | 46 void CallOnUIThreadDelayed(const tracked_objects::Location& from_here, |
46 const base::Closure& closure, | 47 const base::Closure& closure, |
47 int delay_ms) { | 48 int delay_ms) { |
48 if (context_) { | 49 scoped_refptr<base::MessageLoopProxy> message_loop = message_loop_; |
49 context_->PostDelayedTaskToUIThread(from_here, base::Bind( | 50 if (message_loop) { |
| 51 message_loop->PostDelayedTask(from_here, base::Bind( |
50 &UIThreadProxy::CallClosure, this, closure), delay_ms); | 52 &UIThreadProxy::CallClosure, this, closure), delay_ms); |
51 } | 53 } |
52 } | 54 } |
53 | 55 |
54 private: | 56 private: |
55 friend class base::RefCountedThreadSafe<UIThreadProxy>; | 57 friend class base::RefCountedThreadSafe<UIThreadProxy>; |
56 | 58 |
57 virtual ~UIThreadProxy() { } | 59 virtual ~UIThreadProxy() { } |
58 | 60 |
59 void CallClosure(const base::Closure& closure) { | 61 void CallClosure(const base::Closure& closure) { |
60 if (context_) | 62 if (message_loop_) |
61 closure.Run(); | 63 closure.Run(); |
62 } | 64 } |
63 | 65 |
64 ChromotingHostContext* context_; | 66 scoped_refptr<base::MessageLoopProxy> message_loop_; |
65 | 67 |
66 DISALLOW_COPY_AND_ASSIGN(UIThreadProxy); | 68 DISALLOW_COPY_AND_ASSIGN(UIThreadProxy); |
67 }; | 69 }; |
68 | 70 |
69 // static | 71 // static |
70 DesktopEnvironment* DesktopEnvironment::Create(ChromotingHostContext* context) { | 72 DesktopEnvironment* DesktopEnvironment::Create(ChromotingHostContext* context) { |
71 Capturer* capturer = Capturer::Create(); | 73 Capturer* capturer = Capturer::Create(); |
72 EventExecutor* event_executor = | 74 EventExecutor* event_executor = |
73 EventExecutor::Create(context->desktop_message_loop(), capturer); | 75 EventExecutor::Create(context->desktop_message_loop(), capturer); |
74 Curtain* curtain = Curtain::Create(); | 76 Curtain* curtain = Curtain::Create(); |
(...skipping 16 matching lines...) Expand all Loading... |
91 : host_(NULL), | 93 : host_(NULL), |
92 context_(context), | 94 context_(context), |
93 capturer_(capturer), | 95 capturer_(capturer), |
94 event_executor_(event_executor), | 96 event_executor_(event_executor), |
95 curtain_(curtain), | 97 curtain_(curtain), |
96 disconnect_window_(disconnect_window), | 98 disconnect_window_(disconnect_window), |
97 continue_window_(continue_window), | 99 continue_window_(continue_window), |
98 local_input_monitor_(local_input_monitor), | 100 local_input_monitor_(local_input_monitor), |
99 is_monitoring_local_inputs_(false), | 101 is_monitoring_local_inputs_(false), |
100 continue_timer_started_(false), | 102 continue_timer_started_(false), |
101 proxy_(new UIThreadProxy(context)) { | 103 proxy_(new UIThreadProxy(context->ui_message_loop())) { |
102 } | 104 } |
103 | 105 |
104 DesktopEnvironment::~DesktopEnvironment() { | 106 DesktopEnvironment::~DesktopEnvironment() { |
105 } | 107 } |
106 | 108 |
107 void DesktopEnvironment::Shutdown() { | 109 void DesktopEnvironment::Shutdown() { |
108 DCHECK(context_->IsUIThread()); | 110 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
109 | 111 |
110 MonitorLocalInputs(false); | 112 MonitorLocalInputs(false); |
111 ShowDisconnectWindow(false, std::string()); | 113 ShowDisconnectWindow(false, std::string()); |
112 ShowContinueWindow(false); | 114 ShowContinueWindow(false); |
113 StartContinueWindowTimer(false); | 115 StartContinueWindowTimer(false); |
114 | 116 |
115 proxy_->Detach(); | 117 proxy_->Detach(); |
116 } | 118 } |
117 | 119 |
118 void DesktopEnvironment::OnConnect(const std::string& username) { | 120 void DesktopEnvironment::OnConnect(const std::string& username) { |
119 proxy_->CallOnUIThread(FROM_HERE, base::Bind( | 121 proxy_->CallOnUIThread(FROM_HERE, base::Bind( |
120 &DesktopEnvironment::ProcessOnConnect, base::Unretained(this), username)); | 122 &DesktopEnvironment::ProcessOnConnect, base::Unretained(this), username)); |
121 } | 123 } |
122 | 124 |
123 void DesktopEnvironment::OnLastDisconnect() { | 125 void DesktopEnvironment::OnLastDisconnect() { |
124 proxy_->CallOnUIThread(FROM_HERE, base::Bind( | 126 proxy_->CallOnUIThread(FROM_HERE, base::Bind( |
125 &DesktopEnvironment::ProcessOnLastDisconnect, base::Unretained(this))); | 127 &DesktopEnvironment::ProcessOnLastDisconnect, base::Unretained(this))); |
126 } | 128 } |
127 | 129 |
128 void DesktopEnvironment::OnPause(bool pause) { | 130 void DesktopEnvironment::OnPause(bool pause) { |
129 proxy_->CallOnUIThread(FROM_HERE, base::Bind( | 131 proxy_->CallOnUIThread(FROM_HERE, base::Bind( |
130 &DesktopEnvironment::ProcessOnPause, base::Unretained(this), pause)); | 132 &DesktopEnvironment::ProcessOnPause, base::Unretained(this), pause)); |
131 } | 133 } |
132 | 134 |
133 void DesktopEnvironment::ProcessOnConnect(const std::string& username) { | 135 void DesktopEnvironment::ProcessOnConnect(const std::string& username) { |
134 DCHECK(context_->IsUIThread()); | 136 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
135 | 137 |
136 MonitorLocalInputs(true); | 138 MonitorLocalInputs(true); |
137 ShowDisconnectWindow(true, username); | 139 ShowDisconnectWindow(true, username); |
138 StartContinueWindowTimer(true); | 140 StartContinueWindowTimer(true); |
139 } | 141 } |
140 | 142 |
141 void DesktopEnvironment::ProcessOnLastDisconnect() { | 143 void DesktopEnvironment::ProcessOnLastDisconnect() { |
142 DCHECK(context_->IsUIThread()); | 144 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
143 | 145 |
144 MonitorLocalInputs(false); | 146 MonitorLocalInputs(false); |
145 ShowDisconnectWindow(false, std::string()); | 147 ShowDisconnectWindow(false, std::string()); |
146 ShowContinueWindow(false); | 148 ShowContinueWindow(false); |
147 StartContinueWindowTimer(false); | 149 StartContinueWindowTimer(false); |
148 } | 150 } |
149 | 151 |
150 void DesktopEnvironment::ProcessOnPause(bool pause) { | 152 void DesktopEnvironment::ProcessOnPause(bool pause) { |
151 StartContinueWindowTimer(!pause); | 153 StartContinueWindowTimer(!pause); |
152 } | 154 } |
153 | 155 |
154 void DesktopEnvironment::MonitorLocalInputs(bool enable) { | 156 void DesktopEnvironment::MonitorLocalInputs(bool enable) { |
155 DCHECK(context_->IsUIThread()); | 157 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
156 | 158 |
157 if (enable == is_monitoring_local_inputs_) | 159 if (enable == is_monitoring_local_inputs_) |
158 return; | 160 return; |
159 if (enable) { | 161 if (enable) { |
160 local_input_monitor_->Start(host_); | 162 local_input_monitor_->Start(host_); |
161 } else { | 163 } else { |
162 local_input_monitor_->Stop(); | 164 local_input_monitor_->Stop(); |
163 } | 165 } |
164 is_monitoring_local_inputs_ = enable; | 166 is_monitoring_local_inputs_ = enable; |
165 } | 167 } |
166 | 168 |
167 void DesktopEnvironment::ShowDisconnectWindow(bool show, | 169 void DesktopEnvironment::ShowDisconnectWindow(bool show, |
168 const std::string& username) { | 170 const std::string& username) { |
169 DCHECK(context_->IsUIThread()); | 171 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
170 | 172 |
171 if (show) { | 173 if (show) { |
172 disconnect_window_->Show(host_, username); | 174 disconnect_window_->Show(host_, username); |
173 } else { | 175 } else { |
174 disconnect_window_->Hide(); | 176 disconnect_window_->Hide(); |
175 } | 177 } |
176 } | 178 } |
177 | 179 |
178 void DesktopEnvironment::ShowContinueWindow(bool show) { | 180 void DesktopEnvironment::ShowContinueWindow(bool show) { |
179 DCHECK(context_->IsUIThread()); | 181 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
180 | 182 |
181 if (show) { | 183 if (show) { |
182 continue_window_->Show(host_); | 184 continue_window_->Show(host_); |
183 } else { | 185 } else { |
184 continue_window_->Hide(); | 186 continue_window_->Hide(); |
185 } | 187 } |
186 } | 188 } |
187 | 189 |
188 void DesktopEnvironment::StartContinueWindowTimer(bool start) { | 190 void DesktopEnvironment::StartContinueWindowTimer(bool start) { |
189 DCHECK(context_->IsUIThread()); | 191 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
190 | 192 |
191 if (start && ! continue_timer_started_) { | 193 if (start && ! continue_timer_started_) { |
192 continue_timer_target_time_ = base::Time::Now() + | 194 continue_timer_target_time_ = base::Time::Now() + |
193 base::TimeDelta::FromMilliseconds(kContinueWindowTimeoutMs); | 195 base::TimeDelta::FromMilliseconds(kContinueWindowTimeoutMs); |
194 proxy_->CallOnUIThreadDelayed( | 196 proxy_->CallOnUIThreadDelayed( |
195 FROM_HERE, base::Bind(&DesktopEnvironment::ContinueWindowTimerFunc, | 197 FROM_HERE, base::Bind(&DesktopEnvironment::ContinueWindowTimerFunc, |
196 base::Unretained(this)), | 198 base::Unretained(this)), |
197 kContinueWindowTimeoutMs); | 199 kContinueWindowTimeoutMs); |
198 } | 200 } |
199 | 201 |
200 continue_timer_started_ = start; | 202 continue_timer_started_ = start; |
201 } | 203 } |
202 | 204 |
203 void DesktopEnvironment::ContinueWindowTimerFunc() { | 205 void DesktopEnvironment::ContinueWindowTimerFunc() { |
204 DCHECK(context_->IsUIThread()); | 206 DCHECK(context_->ui_message_loop()->BelongsToCurrentThread()); |
205 | 207 |
206 // This function may be called prematurely if timer was stopped and | 208 // This function may be called prematurely if timer was stopped and |
207 // then started again. In that case we just ignore this call. | 209 // then started again. In that case we just ignore this call. |
208 if (continue_timer_target_time_ > base::Time::Now()) | 210 if (continue_timer_target_time_ > base::Time::Now()) |
209 return; | 211 return; |
210 | 212 |
211 host_->PauseSession(true); | 213 host_->PauseSession(true); |
212 ShowContinueWindow(true); | 214 ShowContinueWindow(true); |
213 } | 215 } |
214 | 216 |
215 | 217 |
216 } // namespace remoting | 218 } // namespace remoting |
OLD | NEW |