15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/content_description.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/constants.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/authenticator.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/name_value_map.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using buzz::QName; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using buzz::XmlElement; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char ContentDescription::kChromotingContentName[] = "chromoting"; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDefaultNs[] = ""; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Following constants are used to format session description in XML. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDescriptionTag[] = "description"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kControlTag[] = "control"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEventTag[] = "event"; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kVideoTag[] = "video"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAudioTag[] = "audio"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDeprecatedResolutionTag[] = "initial-resolution"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTransportAttr[] = "transport"; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kVersionAttr[] = "version"; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCodecAttr[] = "codec"; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDeprecatedWidthAttr[] = "width"; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDeprecatedHeightAttr[] = "height"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NameMapElement<ChannelConfig::TransportType> kTransports[] = { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::TRANSPORT_STREAM, "stream" }, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::TRANSPORT_MUX_STREAM, "mux-stream" }, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::TRANSPORT_DATAGRAM, "datagram" }, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::TRANSPORT_NONE, "none" }, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NameMapElement<ChannelConfig::Codec> kCodecs[] = { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::CODEC_VERBATIM, "verbatim" }, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::CODEC_VP8, "vp8" }, 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) { ChannelConfig::CODEC_VP9, "vp9" }, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::CODEC_ZIP, "zip" }, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::CODEC_OPUS, "opus" }, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ChannelConfig::CODEC_SPEEX, "speex" }, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Format a channel configuration tag for chromotocol session description, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// e.g. for video channel: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <video transport="stream" version="1" codec="vp8" /> 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)XmlElement* FormatChannelConfig(const ChannelConfig& config, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& tag_name) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XmlElement* result = new XmlElement( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QName(kChromotingXmlNamespace, tag_name)); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->AddAttr(QName(kDefaultNs, kTransportAttr), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueToName(kTransports, config.transport)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (config.transport != ChannelConfig::TRANSPORT_NONE) { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->AddAttr(QName(kDefaultNs, kVersionAttr), 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::IntToString(config.version)); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (config.codec != ChannelConfig::CODEC_UNDEFINED) { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->AddAttr(QName(kDefaultNs, kCodecAttr), 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ValueToName(kCodecs, config.codec)); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns false if the element is invalid. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseChannelConfig(const XmlElement* element, bool codec_required, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelConfig* config) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NameToValue( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTransports, element->Attr(QName(kDefaultNs, kTransportAttr)), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &config->transport)) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Version is not required when transport="none". 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (config->transport != ChannelConfig::TRANSPORT_NONE) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &config->version)) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Codec is not required when transport="none". 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (codec_required) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NameToValue(kCodecs, element->Attr(QName(kDefaultNs, kCodecAttr)), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &config->codec)) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->codec = ChannelConfig::CODEC_UNDEFINED; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->version = 0; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->codec = ChannelConfig::CODEC_UNDEFINED; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentDescription::ContentDescription( 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CandidateSessionConfig> config, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<buzz::XmlElement> authenticator_message) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : candidate_config_(config.Pass()), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_message_(authenticator_message.Pass()) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentDescription::~ContentDescription() { } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentDescription* ContentDescription::Copy() const { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!candidate_config_.get() || !authenticator_message_.get()) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<XmlElement> message(new XmlElement(*authenticator_message_)); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ContentDescription(candidate_config_->Clone(), message.Pass()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ToXml() creates content description for chromoting session. The 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// description looks as follows: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <description xmlns="google:remoting"> 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <control transport="stream" version="1" /> 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <event transport="datagram" version="1" /> 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <video transport="stream" codec="vp8" version="1" /> 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <audio transport="stream" codec="opus" version="1" /> 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <authentication> 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message created by Authenticator implementation. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// </authentication> 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// </description> 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)XmlElement* ContentDescription::ToXml() const { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XmlElement* root = new XmlElement( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QName(kChromotingXmlNamespace, kDescriptionTag), true); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::list<ChannelConfig>::const_iterator it; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = config()->control_configs().begin(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != config()->control_configs().end(); ++it) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root->AddElement(FormatChannelConfig(*it, kControlTag)); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = config()->event_configs().begin(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != config()->event_configs().end(); ++it) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root->AddElement(FormatChannelConfig(*it, kEventTag)); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = config()->video_configs().begin(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != config()->video_configs().end(); ++it) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root->AddElement(FormatChannelConfig(*it, kVideoTag)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = config()->audio_configs().begin(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != config()->audio_configs().end(); ++it) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelConfig config = *it; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root->AddElement(FormatChannelConfig(config, kAudioTag)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Older endpoints require an initial-resolution tag, but otherwise ignore it. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XmlElement* resolution_tag = new XmlElement( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QName(kChromotingXmlNamespace, kDeprecatedResolutionTag)); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedWidthAttr), "640"); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedHeightAttr), "480"); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root->AddElement(resolution_tag); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (authenticator_message_.get()) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(Authenticator::IsAuthenticatorMessage(authenticator_message_.get())); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root->AddElement(new XmlElement(*authenticator_message_)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return root; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds the channel configs corresponding to |tag_name|, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in |element|, to |configs|. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContentDescription::ParseChannelConfigs( 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const XmlElement* const element, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char tag_name[], 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool codec_required, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool optional, 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::list<ChannelConfig>* const configs) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QName tag(kChromotingXmlNamespace, tag_name); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const XmlElement* child = element->FirstNamed(tag); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (child) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelConfig channel_config; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ParseChannelConfig(child, codec_required, &channel_config)) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) configs->push_back(channel_config); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->NextNamed(tag); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (optional && configs->empty()) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there's no mention of the tag, implicitly assume disabled channel. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) configs->push_back(ChannelConfig::None()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<ContentDescription> ContentDescription::ParseXml( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const XmlElement* element) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element->Name() != QName(kChromotingXmlNamespace, kDescriptionTag)) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Invalid description: " << element->Str(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<ContentDescription>(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CandidateSessionConfig> config( 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateSessionConfig::CreateEmpty()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseChannelConfigs(element, kControlTag, false, false, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->mutable_control_configs()) || 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ParseChannelConfigs(element, kEventTag, false, false, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->mutable_event_configs()) || 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ParseChannelConfigs(element, kVideoTag, true, false, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->mutable_video_configs()) || 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ParseChannelConfigs(element, kAudioTag, true, true, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config->mutable_audio_configs())) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<ContentDescription>(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<XmlElement> authenticator_message; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const XmlElement* child = Authenticator::FindAuthenticatorMessage(element); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) authenticator_message.reset(new XmlElement(*child)); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<ContentDescription>( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ContentDescription(config.Pass(), authenticator_message.Pass())); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protocol 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 243