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/client_session.h" | 5 #include "remoting/host/client_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
10 #include "media/video/capture/screen/screen_capturer.h" | 10 #include "media/video/capture/screen/screen_capturer.h" |
| 11 #include "remoting/base/capabilities.h" |
11 #include "remoting/codec/audio_encoder.h" | 12 #include "remoting/codec/audio_encoder.h" |
12 #include "remoting/codec/audio_encoder_opus.h" | 13 #include "remoting/codec/audio_encoder_opus.h" |
13 #include "remoting/codec/audio_encoder_speex.h" | 14 #include "remoting/codec/audio_encoder_speex.h" |
14 #include "remoting/codec/audio_encoder_verbatim.h" | 15 #include "remoting/codec/audio_encoder_verbatim.h" |
15 #include "remoting/codec/video_encoder.h" | 16 #include "remoting/codec/video_encoder.h" |
16 #include "remoting/codec/video_encoder_verbatim.h" | 17 #include "remoting/codec/video_encoder_verbatim.h" |
17 #include "remoting/codec/video_encoder_vp8.h" | 18 #include "remoting/codec/video_encoder_vp8.h" |
18 #include "remoting/host/audio_capturer.h" | 19 #include "remoting/host/audio_capturer.h" |
19 #include "remoting/host/audio_scheduler.h" | 20 #include "remoting/host/audio_scheduler.h" |
20 #include "remoting/host/desktop_environment.h" | 21 #include "remoting/host/desktop_environment.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 DCHECK(!desktop_environment_); | 90 DCHECK(!desktop_environment_); |
90 DCHECK(!input_injector_); | 91 DCHECK(!input_injector_); |
91 DCHECK(!screen_controls_); | 92 DCHECK(!screen_controls_); |
92 DCHECK(!video_scheduler_); | 93 DCHECK(!video_scheduler_); |
93 | 94 |
94 connection_.reset(); | 95 connection_.reset(); |
95 } | 96 } |
96 | 97 |
97 void ClientSession::NotifyClientResolution( | 98 void ClientSession::NotifyClientResolution( |
98 const protocol::ClientResolution& resolution) { | 99 const protocol::ClientResolution& resolution) { |
| 100 DCHECK(CalledOnValidThread()); |
| 101 |
99 if (!resolution.has_dips_width() || !resolution.has_dips_height()) | 102 if (!resolution.has_dips_width() || !resolution.has_dips_height()) |
100 return; | 103 return; |
101 | 104 |
102 VLOG(1) << "Received ClientResolution (dips_width=" | 105 VLOG(1) << "Received ClientResolution (dips_width=" |
103 << resolution.dips_width() << ", dips_height=" | 106 << resolution.dips_width() << ", dips_height=" |
104 << resolution.dips_height() << ")"; | 107 << resolution.dips_height() << ")"; |
105 | 108 |
106 if (!screen_controls_) | 109 if (!screen_controls_) |
107 return; | 110 return; |
108 | 111 |
109 ScreenResolution client_resolution( | 112 ScreenResolution client_resolution( |
110 SkISize::Make(resolution.dips_width(), resolution.dips_height()), | 113 SkISize::Make(resolution.dips_width(), resolution.dips_height()), |
111 SkIPoint::Make(kDefaultDPI, kDefaultDPI)); | 114 SkIPoint::Make(kDefaultDPI, kDefaultDPI)); |
112 | 115 |
113 // Try to match the client's resolution. | 116 // Try to match the client's resolution. |
114 if (client_resolution.IsValid()) | 117 if (client_resolution.IsValid()) |
115 screen_controls_->SetScreenResolution(client_resolution); | 118 screen_controls_->SetScreenResolution(client_resolution); |
116 } | 119 } |
117 | 120 |
118 void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { | 121 void ClientSession::ControlVideo(const protocol::VideoControl& video_control) { |
| 122 DCHECK(CalledOnValidThread()); |
| 123 |
119 if (video_control.has_enable()) { | 124 if (video_control.has_enable()) { |
120 VLOG(1) << "Received VideoControl (enable=" | 125 VLOG(1) << "Received VideoControl (enable=" |
121 << video_control.enable() << ")"; | 126 << video_control.enable() << ")"; |
122 if (video_scheduler_) | 127 if (video_scheduler_) |
123 video_scheduler_->Pause(!video_control.enable()); | 128 video_scheduler_->Pause(!video_control.enable()); |
124 } | 129 } |
125 } | 130 } |
126 | 131 |
127 void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { | 132 void ClientSession::ControlAudio(const protocol::AudioControl& audio_control) { |
| 133 DCHECK(CalledOnValidThread()); |
| 134 |
128 if (audio_control.has_enable()) { | 135 if (audio_control.has_enable()) { |
129 VLOG(1) << "Received AudioControl (enable=" | 136 VLOG(1) << "Received AudioControl (enable=" |
130 << audio_control.enable() << ")"; | 137 << audio_control.enable() << ")"; |
131 if (audio_scheduler_) | 138 if (audio_scheduler_) |
132 audio_scheduler_->Pause(!audio_control.enable()); | 139 audio_scheduler_->Pause(!audio_control.enable()); |
133 } | 140 } |
134 } | 141 } |
135 | 142 |
| 143 void ClientSession::SetCapabilities( |
| 144 const protocol::Capabilities& capabilities) { |
| 145 DCHECK(CalledOnValidThread()); |
| 146 |
| 147 // The client should not send protocol::Capabilities if it is not supported by |
| 148 // the config channel. |
| 149 if (!connection_->session()->config().SupportsCapabilities()) { |
| 150 LOG(ERROR) << "Unexpected protocol::Capabilities has been received."; |
| 151 return; |
| 152 } |
| 153 |
| 154 // Ignore all the messages but the 1st one. |
| 155 if (client_capabilities_) { |
| 156 LOG(WARNING) << "protocol::Capabilities has been received already."; |
| 157 return; |
| 158 } |
| 159 |
| 160 client_capabilities_ = make_scoped_ptr(new std::string()); |
| 161 if (capabilities.has_capabilities()) |
| 162 *client_capabilities_ = capabilities.capabilities(); |
| 163 |
| 164 VLOG(1) << "Client capabilities: " << *client_capabilities_; |
| 165 |
| 166 // Calculate the set of capabilities enabled by both client and host and |
| 167 // pass it to the desktop environment if it is available. |
| 168 if (desktop_environment_) { |
| 169 desktop_environment_->SetCapabilities( |
| 170 IntersectCapabilities(*client_capabilities_, host_capabilities_)); |
| 171 } |
| 172 } |
| 173 |
136 void ClientSession::OnConnectionAuthenticated( | 174 void ClientSession::OnConnectionAuthenticated( |
137 protocol::ConnectionToClient* connection) { | 175 protocol::ConnectionToClient* connection) { |
138 DCHECK(CalledOnValidThread()); | 176 DCHECK(CalledOnValidThread()); |
139 DCHECK_EQ(connection_.get(), connection); | 177 DCHECK_EQ(connection_.get(), connection); |
| 178 DCHECK(!desktop_environment_); |
140 | 179 |
141 auth_input_filter_.set_enabled(true); | 180 auth_input_filter_.set_enabled(true); |
142 auth_clipboard_filter_.set_enabled(true); | 181 auth_clipboard_filter_.set_enabled(true); |
143 | 182 |
144 clipboard_echo_filter_.set_client_stub(connection_->client_stub()); | 183 clipboard_echo_filter_.set_client_stub(connection_->client_stub()); |
145 mouse_clamping_filter_.set_video_stub(connection_->video_stub()); | 184 mouse_clamping_filter_.set_video_stub(connection_->video_stub()); |
146 | 185 |
147 if (max_duration_ > base::TimeDelta()) { | 186 if (max_duration_ > base::TimeDelta()) { |
148 // TODO(simonmorris): Let Disconnect() tell the client that the | 187 // TODO(simonmorris): Let Disconnect() tell the client that the |
149 // disconnection was caused by the session exceeding its maximum duration. | 188 // disconnection was caused by the session exceeding its maximum duration. |
150 max_duration_timer_.Start(FROM_HERE, max_duration_, | 189 max_duration_timer_.Start(FROM_HERE, max_duration_, |
151 this, &ClientSession::DisconnectSession); | 190 this, &ClientSession::DisconnectSession); |
152 } | 191 } |
153 | 192 |
| 193 // The session may be destroyed as the result result of this call, so it must |
| 194 // be the last in this method. |
154 event_handler_->OnSessionAuthenticated(this); | 195 event_handler_->OnSessionAuthenticated(this); |
155 } | 196 } |
156 | 197 |
157 void ClientSession::OnConnectionChannelsConnected( | 198 void ClientSession::OnConnectionChannelsConnected( |
158 protocol::ConnectionToClient* connection) { | 199 protocol::ConnectionToClient* connection) { |
159 DCHECK(CalledOnValidThread()); | 200 DCHECK(CalledOnValidThread()); |
160 DCHECK_EQ(connection_.get(), connection); | 201 DCHECK_EQ(connection_.get(), connection); |
161 DCHECK(!audio_scheduler_); | 202 DCHECK(!audio_scheduler_); |
162 DCHECK(!desktop_environment_); | |
163 DCHECK(!input_injector_); | 203 DCHECK(!input_injector_); |
164 DCHECK(!screen_controls_); | 204 DCHECK(!screen_controls_); |
165 DCHECK(!video_scheduler_); | 205 DCHECK(!video_scheduler_); |
166 | 206 |
| 207 // Create the desktop environment. |
167 desktop_environment_ = | 208 desktop_environment_ = |
168 desktop_environment_factory_->Create(control_factory_.GetWeakPtr()); | 209 desktop_environment_factory_->Create(control_factory_.GetWeakPtr()); |
| 210 host_capabilities_ = desktop_environment_->GetCapabilities(); |
| 211 |
| 212 // Negotiate capabilities with the client. |
| 213 if (connection_->session()->config().SupportsCapabilities()) { |
| 214 VLOG(1) << "Host capabilities: " << host_capabilities_; |
| 215 |
| 216 protocol::Capabilities capabilities; |
| 217 capabilities.set_capabilities(host_capabilities_); |
| 218 connection_->client_stub()->SetCapabilities(capabilities); |
| 219 |
| 220 // |client_capabilities_| could have been received before all channels were |
| 221 // connected. Process them now. |
| 222 if (client_capabilities_) { |
| 223 desktop_environment_->SetCapabilities( |
| 224 IntersectCapabilities(*client_capabilities_, host_capabilities_)); |
| 225 } |
| 226 } else { |
| 227 VLOG(1) << "The client does not support any capabilities."; |
| 228 |
| 229 client_capabilities_ = make_scoped_ptr(new std::string()); |
| 230 desktop_environment_->SetCapabilities(*client_capabilities_); |
| 231 } |
169 | 232 |
170 // Create the object that controls the screen resolution. | 233 // Create the object that controls the screen resolution. |
171 screen_controls_ = desktop_environment_->CreateScreenControls(); | 234 screen_controls_ = desktop_environment_->CreateScreenControls(); |
172 | 235 |
173 // Create and start the event executor. | 236 // Create and start the event executor. |
174 input_injector_ = desktop_environment_->CreateInputInjector(); | 237 input_injector_ = desktop_environment_->CreateInputInjector(); |
175 input_injector_->Start(CreateClipboardProxy()); | 238 input_injector_->Start(CreateClipboardProxy()); |
176 | 239 |
177 // Connect the host clipboard and input stubs. | 240 // Connect the host clipboard and input stubs. |
178 host_input_filter_.set_input_stub(input_injector_.get()); | 241 host_input_filter_.set_input_stub(input_injector_.get()); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 return scoped_ptr<AudioEncoder>(new AudioEncoderSpeex()); | 402 return scoped_ptr<AudioEncoder>(new AudioEncoderSpeex()); |
340 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { | 403 } else if (audio_config.codec == protocol::ChannelConfig::CODEC_OPUS) { |
341 return scoped_ptr<AudioEncoder>(new AudioEncoderOpus()); | 404 return scoped_ptr<AudioEncoder>(new AudioEncoderOpus()); |
342 } | 405 } |
343 | 406 |
344 NOTIMPLEMENTED(); | 407 NOTIMPLEMENTED(); |
345 return scoped_ptr<AudioEncoder>(NULL); | 408 return scoped_ptr<AudioEncoder>(NULL); |
346 } | 409 } |
347 | 410 |
348 } // namespace remoting | 411 } // namespace remoting |
OLD | NEW |