OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chromoting_host.h" | 5 #include "remoting/host/chromoting_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "remoting/base/constants.h" | 12 #include "remoting/base/constants.h" |
13 #include "remoting/base/encoder.h" | 13 #include "remoting/base/encoder.h" |
14 #include "remoting/base/encoder_row_based.h" | 14 #include "remoting/base/encoder_row_based.h" |
15 #include "remoting/base/encoder_vp8.h" | 15 #include "remoting/base/encoder_vp8.h" |
16 #include "remoting/host/chromoting_host_context.h" | 16 #include "remoting/host/chromoting_host_context.h" |
17 #include "remoting/host/desktop_environment.h" | 17 #include "remoting/host/desktop_environment.h" |
18 #include "remoting/host/event_executor.h" | 18 #include "remoting/host/event_executor.h" |
19 #include "remoting/host/host_config.h" | 19 #include "remoting/host/host_config.h" |
20 #include "remoting/host/screen_recorder.h" | 20 #include "remoting/host/screen_recorder.h" |
21 #include "remoting/jingle_glue/xmpp_signal_strategy.h" | |
22 #include "remoting/protocol/connection_to_client.h" | 21 #include "remoting/protocol/connection_to_client.h" |
23 #include "remoting/protocol/client_stub.h" | 22 #include "remoting/protocol/client_stub.h" |
24 #include "remoting/protocol/host_stub.h" | 23 #include "remoting/protocol/host_stub.h" |
25 #include "remoting/protocol/input_stub.h" | 24 #include "remoting/protocol/input_stub.h" |
26 #include "remoting/protocol/jingle_session_manager.h" | 25 #include "remoting/protocol/jingle_session_manager.h" |
27 #include "remoting/protocol/session_config.h" | 26 #include "remoting/protocol/session_config.h" |
28 #include "remoting/protocol/v1_authenticator.h" | 27 #include "remoting/protocol/v1_authenticator.h" |
29 | 28 |
30 using remoting::protocol::ConnectionToClient; | 29 using remoting::protocol::ConnectionToClient; |
31 using remoting::protocol::InputStub; | 30 using remoting::protocol::InputStub; |
32 | 31 |
33 namespace remoting { | 32 namespace remoting { |
34 | 33 |
35 // static | |
36 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, | |
37 MutableHostConfig* config, | |
38 DesktopEnvironment* environment, | |
39 bool allow_nat_traversal) { | |
40 return new ChromotingHost(context, config, environment, allow_nat_traversal); | |
41 } | |
42 | |
43 ChromotingHost::ChromotingHost(ChromotingHostContext* context, | 34 ChromotingHost::ChromotingHost(ChromotingHostContext* context, |
44 MutableHostConfig* config, | 35 MutableHostConfig* config, |
| 36 SignalStrategy* signal_strategy, |
45 DesktopEnvironment* environment, | 37 DesktopEnvironment* environment, |
46 bool allow_nat_traversal) | 38 bool allow_nat_traversal) |
47 : context_(context), | 39 : context_(context), |
48 desktop_environment_(environment), | 40 desktop_environment_(environment), |
49 config_(config), | 41 config_(config), |
50 allow_nat_traversal_(allow_nat_traversal), | 42 allow_nat_traversal_(allow_nat_traversal), |
51 have_shared_secret_(false), | 43 have_shared_secret_(false), |
| 44 signal_strategy_(signal_strategy), |
52 stopping_recorders_(0), | 45 stopping_recorders_(0), |
53 state_(kInitial), | 46 state_(kInitial), |
54 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), | 47 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()), |
55 is_it2me_(false) { | 48 is_it2me_(false) { |
| 49 DCHECK(context_); |
| 50 DCHECK(signal_strategy); |
56 DCHECK(desktop_environment_); | 51 DCHECK(desktop_environment_); |
57 desktop_environment_->set_host(this); | 52 desktop_environment_->set_host(this); |
58 } | 53 } |
59 | 54 |
60 ChromotingHost::~ChromotingHost() { | 55 ChromotingHost::~ChromotingHost() { |
61 DCHECK(clients_.empty()); | 56 DCHECK(clients_.empty()); |
62 } | 57 } |
63 | 58 |
64 void ChromotingHost::Start() { | 59 void ChromotingHost::Start() { |
65 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 60 if (!context_->network_message_loop()->BelongsToCurrentThread()) { |
66 context_->network_message_loop()->PostTask( | 61 context_->network_message_loop()->PostTask( |
67 FROM_HERE, base::Bind(&ChromotingHost::Start, this)); | 62 FROM_HERE, base::Bind(&ChromotingHost::Start, this)); |
68 return; | 63 return; |
69 } | 64 } |
70 | 65 |
71 LOG(INFO) << "Starting host"; | 66 LOG(INFO) << "Starting host"; |
72 DCHECK(!signal_strategy_.get()); | |
73 | 67 |
74 // Make sure this object is not started. | 68 // Make sure this object is not started. |
75 if (state_ != kInitial) | 69 if (state_ != kInitial) |
76 return; | 70 return; |
77 state_ = kStarted; | 71 state_ = kStarted; |
78 | 72 |
79 // Assign key and certificate to server. | 73 // Assign key and certificate to server. |
80 if (!key_pair_.Load(config_)) { | 74 if (!key_pair_.Load(config_)) { |
81 LOG(ERROR) << "Failed to load key pair for the host."; | 75 LOG(ERROR) << "Failed to load key pair for the host."; |
82 return; | 76 return; |
83 } | 77 } |
84 | 78 |
85 // Use an XMPP connection to the Talk network for session signalling. | |
86 std::string xmpp_login; | |
87 std::string xmpp_auth_token; | |
88 std::string xmpp_auth_service; | |
89 if (!config_->GetString(kXmppLoginConfigPath, &xmpp_login) || | |
90 !config_->GetString(kXmppAuthTokenConfigPath, &xmpp_auth_token) || | |
91 !config_->GetString(kXmppAuthServiceConfigPath, &xmpp_auth_service)) { | |
92 LOG(ERROR) << "XMPP credentials are not defined in the config."; | |
93 return; | |
94 } | |
95 | |
96 // Create and start XMPP connection. | |
97 signal_strategy_.reset( | |
98 new XmppSignalStrategy(context_->jingle_thread(), xmpp_login, | |
99 xmpp_auth_token, xmpp_auth_service)); | |
100 signal_strategy_->AddListener(this); | |
101 signal_strategy_->Connect(); | |
102 | |
103 // Create and start session manager. | 79 // Create and start session manager. |
104 session_manager_.reset( | 80 session_manager_.reset( |
105 new protocol::JingleSessionManager(context_->network_message_loop())); | 81 new protocol::JingleSessionManager(context_->network_message_loop())); |
106 session_manager_->Init(signal_strategy_.get(), | 82 session_manager_->Init(signal_strategy_, this, allow_nat_traversal_); |
107 this, allow_nat_traversal_); | |
108 } | 83 } |
109 | 84 |
110 // This method is called when we need to destroy the host process. | 85 // This method is called when we need to destroy the host process. |
111 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { | 86 void ChromotingHost::Shutdown(const base::Closure& shutdown_task) { |
112 if (!context_->network_message_loop()->BelongsToCurrentThread()) { | 87 if (!context_->network_message_loop()->BelongsToCurrentThread()) { |
113 context_->network_message_loop()->PostTask( | 88 context_->network_message_loop()->PostTask( |
114 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); | 89 FROM_HERE, base::Bind(&ChromotingHost::Shutdown, this, shutdown_task)); |
115 return; | 90 return; |
116 } | 91 } |
117 | 92 |
(...skipping 20 matching lines...) Expand all Loading... |
138 session_manager_->Close(); | 113 session_manager_->Close(); |
139 // It may not be safe to delete |session_manager_| here becase | 114 // It may not be safe to delete |session_manager_| here becase |
140 // this method may be invoked in response to a libjingle event and | 115 // this method may be invoked in response to a libjingle event and |
141 // libjingle's sigslot doesn't handle it properly, so postpone the | 116 // libjingle's sigslot doesn't handle it properly, so postpone the |
142 // deletion. | 117 // deletion. |
143 context_->network_message_loop()->DeleteSoon( | 118 context_->network_message_loop()->DeleteSoon( |
144 FROM_HERE, session_manager_.release()); | 119 FROM_HERE, session_manager_.release()); |
145 have_shared_secret_ = false; | 120 have_shared_secret_ = false; |
146 } | 121 } |
147 | 122 |
148 // Stop XMPP connection synchronously. | |
149 if (signal_strategy_.get()) { | |
150 signal_strategy_->Disconnect(); | |
151 signal_strategy_->RemoveListener(this); | |
152 signal_strategy_.reset(); | |
153 } | |
154 | |
155 if (recorder_.get()) { | 123 if (recorder_.get()) { |
156 StopScreenRecorder(); | 124 StopScreenRecorder(); |
157 } else { | 125 } else { |
158 ShutdownFinish(); | 126 ShutdownFinish(); |
159 } | 127 } |
160 } | 128 } |
161 | 129 |
162 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { | 130 void ChromotingHost::AddStatusObserver(HostStatusObserver* observer) { |
163 DCHECK_EQ(state_, kInitial); | 131 DCHECK_EQ(state_, kInitial); |
164 status_observers_.push_back(observer); | 132 status_observers_.push_back(observer); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 } | 215 } |
248 } | 216 } |
249 | 217 |
250 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, | 218 void ChromotingHost::OnSessionSequenceNumber(ClientSession* session, |
251 int64 sequence_number) { | 219 int64 sequence_number) { |
252 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 220 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); |
253 if (recorder_.get()) | 221 if (recorder_.get()) |
254 recorder_->UpdateSequenceNumber(sequence_number); | 222 recorder_->UpdateSequenceNumber(sequence_number); |
255 } | 223 } |
256 | 224 |
257 //////////////////////////////////////////////////////////////////////////// | |
258 // SignalStrategy::StatusObserver implementations | |
259 void ChromotingHost::OnSignalStrategyStateChange( | |
260 SignalStrategy::State state) { | |
261 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | |
262 | |
263 if (state == SignalStrategy::CONNECTED) { | |
264 LOG(INFO) << "Host connected as " << signal_strategy_->GetLocalJid(); | |
265 | |
266 for (StatusObserverList::iterator it = status_observers_.begin(); | |
267 it != status_observers_.end(); ++it) { | |
268 (*it)->OnSignallingConnected(signal_strategy_.get()); | |
269 } | |
270 } else if (state == SignalStrategy::DISCONNECTED) { | |
271 LOG(INFO) << "Host disconnected from talk network."; | |
272 for (StatusObserverList::iterator it = status_observers_.begin(); | |
273 it != status_observers_.end(); ++it) { | |
274 (*it)->OnSignallingDisconnected(); | |
275 } | |
276 } | |
277 } | |
278 | |
279 void ChromotingHost::OnSessionManagerReady() { | 225 void ChromotingHost::OnSessionManagerReady() { |
280 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 226 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); |
281 // Don't need to do anything here, just wait for incoming | 227 // Don't need to do anything here, just wait for incoming |
282 // connections. | 228 // connections. |
283 } | 229 } |
284 | 230 |
285 void ChromotingHost::OnIncomingSession( | 231 void ChromotingHost::OnIncomingSession( |
286 protocol::Session* session, | 232 protocol::Session* session, |
287 protocol::SessionManager::IncomingSessionResponse* response) { | 233 protocol::SessionManager::IncomingSessionResponse* response) { |
288 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); | 234 DCHECK(context_->network_message_loop()->BelongsToCurrentThread()); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 } | 378 } |
433 | 379 |
434 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); | 380 for (std::vector<base::Closure>::iterator it = shutdown_tasks_.begin(); |
435 it != shutdown_tasks_.end(); ++it) { | 381 it != shutdown_tasks_.end(); ++it) { |
436 it->Run(); | 382 it->Run(); |
437 } | 383 } |
438 shutdown_tasks_.clear(); | 384 shutdown_tasks_.clear(); |
439 } | 385 } |
440 | 386 |
441 } // namespace remoting | 387 } // namespace remoting |
OLD | NEW |