Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(480)

Side by Side Diff: remoting/host/chromoting_host.cc

Issue 6266010: Fix crashes in ChromotingHost (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/chromoting_host.h ('k') | remoting/host/chromoting_host_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/stl_util-inl.h" 7 #include "base/stl_util-inl.h"
8 #include "base/task.h" 8 #include "base/task.h"
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 #include "remoting/base/constants.h" 10 #include "remoting/base/constants.h"
11 #include "remoting/base/encoder.h" 11 #include "remoting/base/encoder.h"
12 #include "remoting/base/encoder_row_based.h" 12 #include "remoting/base/encoder_row_based.h"
13 #include "remoting/base/encoder_vp8.h" 13 #include "remoting/base/encoder_vp8.h"
14 #include "remoting/host/capturer.h" 14 #include "remoting/host/capturer.h"
15 #include "remoting/host/chromoting_host_context.h" 15 #include "remoting/host/chromoting_host_context.h"
16 #include "remoting/host/event_executor.h" 16 #include "remoting/host/event_executor.h"
17 #include "remoting/host/host_config.h" 17 #include "remoting/host/host_config.h"
18 #include "remoting/host/host_stub_fake.h" 18 #include "remoting/host/host_stub_fake.h"
19 #include "remoting/host/screen_recorder.h" 19 #include "remoting/host/screen_recorder.h"
20 #include "remoting/protocol/connection_to_client.h" 20 #include "remoting/protocol/connection_to_client.h"
21 #include "remoting/protocol/host_stub.h" 21 #include "remoting/protocol/host_stub.h"
22 #include "remoting/protocol/input_stub.h" 22 #include "remoting/protocol/input_stub.h"
23 #include "remoting/protocol/jingle_session_manager.h" 23 #include "remoting/protocol/jingle_session_manager.h"
24 #include "remoting/protocol/session_config.h" 24 #include "remoting/protocol/session_config.h"
25 25
26 using remoting::protocol::ConnectionToClient; 26 using remoting::protocol::ConnectionToClient;
27 using remoting::protocol::InputStub;
27 28
28 namespace remoting { 29 namespace remoting {
29 30
30 // static 31 // static
31 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, 32 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context,
32 MutableHostConfig* config) { 33 MutableHostConfig* config) {
33 return Create(context, config, 34 Capturer* capturer = Capturer::Create(context->main_message_loop());
34 Capturer::Create(context->main_message_loop())); 35 InputStub* input_stub = CreateEventExecutor(context->main_message_loop(),
36 capturer);
37 return Create(context, config, capturer, input_stub);
35 } 38 }
36 39
37 // static 40 // static
38 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context, 41 ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context,
39 MutableHostConfig* config, 42 MutableHostConfig* config,
40 Capturer* capturer) { 43 Capturer* capturer,
41 return new ChromotingHost(context, config, capturer); 44 InputStub* input_stub) {
45 return new ChromotingHost(context, config, capturer, input_stub);
42 } 46 }
43 47
44 ChromotingHost::ChromotingHost(ChromotingHostContext* context, 48 ChromotingHost::ChromotingHost(ChromotingHostContext* context,
45 MutableHostConfig* config, Capturer* capturer) 49 MutableHostConfig* config,
50 Capturer* capturer,
51 InputStub* input_stub)
46 : context_(context), 52 : context_(context),
47 config_(config), 53 config_(config),
48 capturer_(capturer), 54 capturer_(capturer),
49 input_stub_(CreateEventExecutor( 55 input_stub_(input_stub),
50 context->main_message_loop(), capturer)),
51 host_stub_(new HostStubFake()), 56 host_stub_(new HostStubFake()),
52 state_(kInitial), 57 state_(kInitial),
53 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()) { 58 protocol_config_(protocol::CandidateSessionConfig::CreateDefault()) {
54 } 59 }
55 60
56 61
57 ChromotingHost::~ChromotingHost() { 62 ChromotingHost::~ChromotingHost() {
58 } 63 }
59 64
60 void ChromotingHost::Start(Task* shutdown_task) { 65 void ChromotingHost::Start(Task* shutdown_task) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 // No-op if this object is not started yet. 119 // No-op if this object is not started yet.
115 { 120 {
116 AutoLock auto_lock(lock_); 121 AutoLock auto_lock(lock_);
117 if (state_ != kStarted) { 122 if (state_ != kStarted) {
118 state_ = kStopped; 123 state_ = kStopped;
119 return; 124 return;
120 } 125 }
121 state_ = kStopped; 126 state_ = kStopped;
122 } 127 }
123 128
124 // Tell the session to stop and then disconnect all clients.
125 if (recorder_.get()) {
126 recorder_->Stop(NULL);
127 recorder_->RemoveAllConnections();
128 }
129
130 // Disconnect the client. 129 // Disconnect the client.
131 if (connection_) { 130 if (connection_) {
132 connection_->Disconnect(); 131 connection_->Disconnect();
133 } 132 }
134 133
135 // Stop the heartbeat sender. 134 // Stop the heartbeat sender.
136 if (heartbeat_sender_) { 135 if (heartbeat_sender_) {
137 heartbeat_sender_->Stop(); 136 heartbeat_sender_->Stop();
138 } 137 }
139 138
140 // Stop chromotocol session manager. 139 // Stop chromotocol session manager.
141 if (session_manager_) { 140 if (session_manager_) {
142 session_manager_->Close( 141 session_manager_->Close(
143 NewRunnableMethod(this, &ChromotingHost::OnServerClosed)); 142 NewRunnableMethod(this, &ChromotingHost::OnServerClosed));
144 } 143 }
145 144
146 // Disconnect from the talk network. 145 // Disconnect from the talk network.
147 if (jingle_client_) { 146 if (jingle_client_) {
148 jingle_client_->Close(); 147 jingle_client_->Close();
149 } 148 }
150 149
151 // Lastly call the shutdown task. 150 // Tell the recorder to stop and then disconnect all clients.
152 if (shutdown_task_.get()) { 151 if (recorder_.get()) {
152 recorder_->RemoveAllConnections();
153 recorder_->Stop(shutdown_task_.release());
154 } else {
153 shutdown_task_->Run(); 155 shutdown_task_->Run();
156 shutdown_task_.reset();
154 } 157 }
155 } 158 }
156 159
157 // This method is called when a client connects. 160 // This method is called when a client connects.
158 void ChromotingHost::OnClientConnected(ConnectionToClient* connection) { 161 void ChromotingHost::OnClientConnected(ConnectionToClient* connection) {
159 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 162 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
160 163
161 // Create a new RecordSession if there was none. 164 // Create a new RecordSession if there was none.
162 if (!recorder_.get()) { 165 if (!recorder_.get()) {
163 // Then we create a ScreenRecorder passing the message loops that 166 // Then we create a ScreenRecorder passing the message loops that
164 // it should run on. 167 // it should run on.
165 DCHECK(capturer_.get()); 168 DCHECK(capturer_.get());
166 169
167 Encoder* encoder = CreateEncoder(connection->session()->config()); 170 Encoder* encoder = CreateEncoder(connection->session()->config());
168 171
169 recorder_ = new ScreenRecorder(context_->main_message_loop(), 172 recorder_ = new ScreenRecorder(context_->main_message_loop(),
170 context_->encode_message_loop(), 173 context_->encode_message_loop(),
171 context_->network_message_loop(), 174 context_->network_message_loop(),
172 capturer_.release(), 175 capturer_.get(),
173 encoder); 176 encoder);
174 } 177 }
175 178
176 // Immediately add the connection and start the session. 179 // Immediately add the connection and start the session.
177 recorder_->AddConnection(connection); 180 recorder_->AddConnection(connection);
178 recorder_->Start(); 181 recorder_->Start();
179 VLOG(1) << "Session manager started"; 182 VLOG(1) << "Session manager started";
180 } 183 }
181 184
182 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) { 185 void ChromotingHost::OnClientDisconnected(ConnectionToClient* connection) {
183 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current()); 186 DCHECK_EQ(context_->main_message_loop(), MessageLoop::current());
184 187
185 // Remove the connection from the session manager and stop the session. 188 // Remove the connection from the session manager and stop the session.
186 // TODO(hclam): Stop only if the last connection disconnected. 189 // TODO(hclam): Stop only if the last connection disconnected.
187 if (recorder_.get()) { 190 if (recorder_.get()) {
188 recorder_->RemoveConnection(connection); 191 recorder_->RemoveConnection(connection);
189 recorder_->Stop(NULL); 192 recorder_->Stop(NULL);
193 recorder_ = NULL;
190 } 194 }
191 195
192 // Close the connection to connection just to be safe. 196 // Close the connection to connection just to be safe.
193 connection->Disconnect(); 197 connection->Disconnect();
194 198
195 // Also remove reference to ConnectionToClient from this object. 199 // Also remove reference to ConnectionToClient from this object.
196 connection_ = NULL; 200 connection_ = NULL;
197 } 201 }
198 202
199 //////////////////////////////////////////////////////////////////////////// 203 ////////////////////////////////////////////////////////////////////////////
200 // protocol::ConnectionToClient::EventHandler implementations 204 // protocol::ConnectionToClient::EventHandler implementations
201 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { 205 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) {
202 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); 206 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current());
203 207
204 // Completes the connection to the client. 208 // Completes the connection to the client.
205 VLOG(1) << "Connection to client established."; 209 VLOG(1) << "Connection to client established.";
206 context_->main_message_loop()->PostTask( 210 context_->main_message_loop()->PostTask(
207 FROM_HERE, 211 FROM_HERE,
208 NewRunnableMethod(this, &ChromotingHost::OnClientConnected, 212 NewRunnableMethod(this, &ChromotingHost::OnClientConnected,
209 connection_)); 213 make_scoped_refptr(connection)));
210 } 214 }
211 215
212 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { 216 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) {
213 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); 217 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current());
214 218
215 VLOG(1) << "Connection to client closed."; 219 VLOG(1) << "Connection to client closed.";
216 context_->main_message_loop()->PostTask( 220 context_->main_message_loop()->PostTask(
217 FROM_HERE, 221 FROM_HERE,
218 NewRunnableMethod(this, &ChromotingHost::OnClientDisconnected, 222 NewRunnableMethod(this, &ChromotingHost::OnClientDisconnected,
219 connection_)); 223 make_scoped_refptr(connection)));
220 } 224 }
221 225
222 void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) { 226 void ChromotingHost::OnConnectionFailed(ConnectionToClient* connection) {
223 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); 227 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current());
224 228
225 LOG(ERROR) << "Connection failed unexpectedly."; 229 LOG(ERROR) << "Connection failed unexpectedly.";
226 context_->main_message_loop()->PostTask( 230 context_->main_message_loop()->PostTask(
227 FROM_HERE, 231 FROM_HERE,
228 NewRunnableMethod(this, &ChromotingHost::OnClientDisconnected, 232 NewRunnableMethod(this, &ChromotingHost::OnClientDisconnected,
229 connection_)); 233 make_scoped_refptr(connection)));
230 } 234 }
231 235
232 //////////////////////////////////////////////////////////////////////////// 236 ////////////////////////////////////////////////////////////////////////////
233 // JingleClient::Callback implementations 237 // JingleClient::Callback implementations
234 void ChromotingHost::OnStateChange(JingleClient* jingle_client, 238 void ChromotingHost::OnStateChange(JingleClient* jingle_client,
235 JingleClient::State state) { 239 JingleClient::State state) {
236 if (state == JingleClient::CONNECTED) { 240 if (state == JingleClient::CONNECTED) {
237 DCHECK_EQ(jingle_client_.get(), jingle_client); 241 DCHECK_EQ(jingle_client_.get(), jingle_client);
238 VLOG(1) << "Host connected as " << jingle_client->GetFullJid(); 242 VLOG(1) << "Host connected as " << jingle_client->GetFullJid();
239 243
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 296 }
293 297
294 session->set_config(config); 298 session->set_config(config);
295 session->set_receiver_token( 299 session->set_receiver_token(
296 GenerateHostAuthToken(session->initiator_token())); 300 GenerateHostAuthToken(session->initiator_token()));
297 301
298 *response = protocol::SessionManager::ACCEPT; 302 *response = protocol::SessionManager::ACCEPT;
299 303
300 VLOG(1) << "Client connected: " << session->jid(); 304 VLOG(1) << "Client connected: " << session->jid();
301 305
302 // If we accept the connected then create a client object and set the 306 // If we accept the connected then create a connection object.
303 // callback.
304 connection_ = new ConnectionToClient(context_->network_message_loop(), 307 connection_ = new ConnectionToClient(context_->network_message_loop(),
305 this, host_stub_.get(), 308 this, host_stub_.get(),
306 input_stub_.get()); 309 input_stub_.get());
307 connection_->Init(session); 310 connection_->Init(session);
308 } 311 }
309 312
310 void ChromotingHost::set_protocol_config( 313 void ChromotingHost::set_protocol_config(
311 protocol::CandidateSessionConfig* config) { 314 protocol::CandidateSessionConfig* config) {
312 DCHECK(config_.get()); 315 DCHECK(config_.get());
313 DCHECK_EQ(state_, kInitial); 316 DCHECK_EQ(state_, kInitial);
(...skipping 23 matching lines...) Expand all
337 return NULL; 340 return NULL;
338 } 341 }
339 342
340 std::string ChromotingHost::GenerateHostAuthToken( 343 std::string ChromotingHost::GenerateHostAuthToken(
341 const std::string& encoded_client_token) { 344 const std::string& encoded_client_token) {
342 // TODO(ajwong): Return the signature of this instead. 345 // TODO(ajwong): Return the signature of this instead.
343 return encoded_client_token; 346 return encoded_client_token;
344 } 347 }
345 348
346 } // namespace remoting 349 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/chromoting_host.h ('k') | remoting/host/chromoting_host_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698