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/protocol/content_description.h" | 5 #include "remoting/protocol/content_description.h" |
6 | 6 |
| 7 #include "base/base64.h" |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
9 #include "remoting/base/constants.h" | 10 #include "remoting/base/constants.h" |
10 #include "remoting/protocol/authenticator.h" | 11 #include "remoting/protocol/authenticator.h" |
11 #include "remoting/protocol/name_value_map.h" | 12 #include "remoting/protocol/name_value_map.h" |
12 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 13 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
13 | 14 |
14 using buzz::QName; | 15 using buzz::QName; |
15 using buzz::XmlElement; | 16 using buzz::XmlElement; |
16 | 17 |
17 namespace remoting { | 18 namespace remoting { |
18 namespace protocol { | 19 namespace protocol { |
19 | 20 |
20 const char ContentDescription::kChromotingContentName[] = "chromoting"; | 21 const char ContentDescription::kChromotingContentName[] = "chromoting"; |
21 | 22 |
22 namespace { | 23 namespace { |
23 | 24 |
24 const char kDefaultNs[] = ""; | 25 const char kDefaultNs[] = ""; |
25 | 26 |
26 // Following constants are used to format session description in XML. | 27 // Following constants are used to format session description in XML. |
27 const char kDescriptionTag[] = "description"; | 28 const char kDescriptionTag[] = "description"; |
28 const char kStandardIceTag[] = "standard-ice"; | 29 const char kStandardIceTag[] = "standard-ice"; |
29 const char kControlTag[] = "control"; | 30 const char kControlTag[] = "control"; |
30 const char kEventTag[] = "event"; | 31 const char kEventTag[] = "event"; |
31 const char kVideoTag[] = "video"; | 32 const char kVideoTag[] = "video"; |
32 const char kAudioTag[] = "audio"; | 33 const char kAudioTag[] = "audio"; |
33 const char kVp9ExperimentTag[] = "vp9-experiment"; | 34 const char kVp9ExperimentTag[] = "vp9-experiment"; |
34 const char kDeprecatedResolutionTag[] = "initial-resolution"; | 35 const char kDeprecatedResolutionTag[] = "initial-resolution"; |
| 36 const char kQuicConfigTag[] = "quic-config"; |
35 | 37 |
36 const char kTransportAttr[] = "transport"; | 38 const char kTransportAttr[] = "transport"; |
37 const char kVersionAttr[] = "version"; | 39 const char kVersionAttr[] = "version"; |
38 const char kCodecAttr[] = "codec"; | 40 const char kCodecAttr[] = "codec"; |
39 const char kDeprecatedWidthAttr[] = "width"; | 41 const char kDeprecatedWidthAttr[] = "width"; |
40 const char kDeprecatedHeightAttr[] = "height"; | 42 const char kDeprecatedHeightAttr[] = "height"; |
41 | 43 |
42 const NameMapElement<ChannelConfig::TransportType> kTransports[] = { | 44 const NameMapElement<ChannelConfig::TransportType> kTransports[] = { |
43 { ChannelConfig::TRANSPORT_STREAM, "stream" }, | 45 { ChannelConfig::TRANSPORT_STREAM, "stream" }, |
44 { ChannelConfig::TRANSPORT_MUX_STREAM, "mux-stream" }, | 46 { ChannelConfig::TRANSPORT_MUX_STREAM, "mux-stream" }, |
| 47 { ChannelConfig::TRANSPORT_QUIC_STREAM, "quic-stream" }, |
45 { ChannelConfig::TRANSPORT_DATAGRAM, "datagram" }, | 48 { ChannelConfig::TRANSPORT_DATAGRAM, "datagram" }, |
46 { ChannelConfig::TRANSPORT_NONE, "none" }, | 49 { ChannelConfig::TRANSPORT_NONE, "none" }, |
47 }; | 50 }; |
48 | 51 |
49 const NameMapElement<ChannelConfig::Codec> kCodecs[] = { | 52 const NameMapElement<ChannelConfig::Codec> kCodecs[] = { |
50 { ChannelConfig::CODEC_VERBATIM, "verbatim" }, | 53 { ChannelConfig::CODEC_VERBATIM, "verbatim" }, |
51 { ChannelConfig::CODEC_VP8, "vp8" }, | 54 { ChannelConfig::CODEC_VP8, "vp8" }, |
52 { ChannelConfig::CODEC_VP9, "vp9" }, | 55 { ChannelConfig::CODEC_VP9, "vp9" }, |
53 { ChannelConfig::CODEC_ZIP, "zip" }, | 56 { ChannelConfig::CODEC_ZIP, "zip" }, |
54 { ChannelConfig::CODEC_OPUS, "opus" }, | 57 { ChannelConfig::CODEC_OPUS, "opus" }, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 config->codec = ChannelConfig::CODEC_UNDEFINED; | 112 config->codec = ChannelConfig::CODEC_UNDEFINED; |
110 } | 113 } |
111 | 114 |
112 return true; | 115 return true; |
113 } | 116 } |
114 | 117 |
115 } // namespace | 118 } // namespace |
116 | 119 |
117 ContentDescription::ContentDescription( | 120 ContentDescription::ContentDescription( |
118 scoped_ptr<CandidateSessionConfig> config, | 121 scoped_ptr<CandidateSessionConfig> config, |
119 scoped_ptr<buzz::XmlElement> authenticator_message) | 122 scoped_ptr<buzz::XmlElement> authenticator_message, |
| 123 const std::string& quic_config_message) |
120 : candidate_config_(config.Pass()), | 124 : candidate_config_(config.Pass()), |
121 authenticator_message_(authenticator_message.Pass()) { | 125 authenticator_message_(authenticator_message.Pass()), |
| 126 quic_config_message_(quic_config_message) { |
122 } | 127 } |
123 | 128 |
124 ContentDescription::~ContentDescription() { } | 129 ContentDescription::~ContentDescription() { } |
125 | 130 |
126 // ToXml() creates content description for chromoting session. The | 131 // ToXml() creates content description for chromoting session. The |
127 // description looks as follows: | 132 // description looks as follows: |
128 // <description xmlns="google:remoting"> | 133 // <description xmlns="google:remoting"> |
129 // <standard-ice/> | 134 // <standard-ice/> |
130 // <control transport="stream" version="1" /> | 135 // <control transport="stream" version="1" /> |
131 // <event transport="datagram" version="1" /> | 136 // <event transport="datagram" version="1" /> |
(...skipping 29 matching lines...) Expand all Loading... |
161 root->AddElement(FormatChannelConfig(channel_config, kAudioTag)); | 166 root->AddElement(FormatChannelConfig(channel_config, kAudioTag)); |
162 } | 167 } |
163 | 168 |
164 // Older endpoints require an initial-resolution tag, but otherwise ignore it. | 169 // Older endpoints require an initial-resolution tag, but otherwise ignore it. |
165 XmlElement* resolution_tag = new XmlElement( | 170 XmlElement* resolution_tag = new XmlElement( |
166 QName(kChromotingXmlNamespace, kDeprecatedResolutionTag)); | 171 QName(kChromotingXmlNamespace, kDeprecatedResolutionTag)); |
167 resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedWidthAttr), "640"); | 172 resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedWidthAttr), "640"); |
168 resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedHeightAttr), "480"); | 173 resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedHeightAttr), "480"); |
169 root->AddElement(resolution_tag); | 174 root->AddElement(resolution_tag); |
170 | 175 |
171 if (authenticator_message_.get()) { | 176 if (authenticator_message_) { |
172 DCHECK(Authenticator::IsAuthenticatorMessage(authenticator_message_.get())); | 177 DCHECK(Authenticator::IsAuthenticatorMessage(authenticator_message_.get())); |
173 root->AddElement(new XmlElement(*authenticator_message_)); | 178 root->AddElement(new XmlElement(*authenticator_message_)); |
174 } | 179 } |
175 | 180 |
| 181 if (!quic_config_message_.empty()) { |
| 182 XmlElement* quic_config_tag = |
| 183 new XmlElement(QName(kChromotingXmlNamespace, kQuicConfigTag)); |
| 184 root->AddElement(quic_config_tag); |
| 185 std::string config_base64; |
| 186 base::Base64Encode(quic_config_message_, &config_base64); |
| 187 quic_config_tag->SetBodyText(config_base64); |
| 188 } |
| 189 |
176 if (config()->vp9_experiment_enabled()) { | 190 if (config()->vp9_experiment_enabled()) { |
177 root->AddElement( | 191 root->AddElement( |
178 new XmlElement(QName(kChromotingXmlNamespace, kVp9ExperimentTag))); | 192 new XmlElement(QName(kChromotingXmlNamespace, kVp9ExperimentTag))); |
179 } | 193 } |
180 | 194 |
181 return root; | 195 return root; |
182 } | 196 } |
183 | 197 |
184 // static | 198 // static |
185 // Adds the channel configs corresponding to |tag_name|, | 199 // Adds the channel configs corresponding to |tag_name|, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 // Check if VP9 experiment is enabled. | 248 // Check if VP9 experiment is enabled. |
235 if (element->FirstNamed(QName(kChromotingXmlNamespace, kVp9ExperimentTag))) { | 249 if (element->FirstNamed(QName(kChromotingXmlNamespace, kVp9ExperimentTag))) { |
236 config->set_vp9_experiment_enabled(true); | 250 config->set_vp9_experiment_enabled(true); |
237 } | 251 } |
238 | 252 |
239 scoped_ptr<XmlElement> authenticator_message; | 253 scoped_ptr<XmlElement> authenticator_message; |
240 const XmlElement* child = Authenticator::FindAuthenticatorMessage(element); | 254 const XmlElement* child = Authenticator::FindAuthenticatorMessage(element); |
241 if (child) | 255 if (child) |
242 authenticator_message.reset(new XmlElement(*child)); | 256 authenticator_message.reset(new XmlElement(*child)); |
243 | 257 |
244 return make_scoped_ptr( | 258 std::string quic_config_message; |
245 new ContentDescription(config.Pass(), authenticator_message.Pass())); | 259 const XmlElement* quic_config_tag = |
| 260 element->FirstNamed(QName(kChromotingXmlNamespace, kQuicConfigTag)); |
| 261 if (quic_config_tag) { |
| 262 if (!base::Base64Decode(quic_config_tag->BodyText(), |
| 263 &quic_config_message)) { |
| 264 LOG(ERROR) << "Failed to parse QUIC config."; |
| 265 return nullptr; |
| 266 } |
| 267 } |
| 268 |
| 269 return make_scoped_ptr(new ContentDescription( |
| 270 config.Pass(), authenticator_message.Pass(), quic_config_message)); |
246 } | 271 } |
247 | 272 |
248 } // namespace protocol | 273 } // namespace protocol |
249 } // namespace remoting | 274 } // namespace remoting |
OLD | NEW |