Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / remoting / protocol / session_config.cc
blob8994aa1e63c64e2af100d888f31f19329092232c
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
3 // found in the LICENSE file.
5 #include "remoting/protocol/session_config.h"
7 #include <algorithm>
9 #include "base/logging.h"
11 namespace remoting {
12 namespace protocol {
14 namespace {
16 bool IsChannelConfigSupported(const std::list<ChannelConfig>& list,
17 const ChannelConfig& value) {
18 return std::find(list.begin(), list.end(), value) != list.end();
21 bool SelectCommonChannelConfig(const std::list<ChannelConfig>& host_configs,
22 const std::list<ChannelConfig>& client_configs,
23 ChannelConfig* config) {
24 // Usually each of these lists will contain just a few elements, so iterating
25 // over all of them is not a problem.
26 std::list<ChannelConfig>::const_iterator it;
27 for (it = client_configs.begin(); it != client_configs.end(); ++it) {
28 if (IsChannelConfigSupported(host_configs, *it)) {
29 *config = *it;
30 return true;
33 return false;
36 } // namespace
38 const int kDefaultStreamVersion = 2;
39 const int kControlStreamVersion = 3;
41 ChannelConfig ChannelConfig::None() {
42 return ChannelConfig();
45 ChannelConfig::ChannelConfig(TransportType transport, int version, Codec codec)
46 : transport(transport),
47 version(version),
48 codec(codec) {
51 bool ChannelConfig::operator==(const ChannelConfig& b) const {
52 // If the transport field is set to NONE then all other fields are irrelevant.
53 if (transport == ChannelConfig::TRANSPORT_NONE)
54 return transport == b.transport;
55 return transport == b.transport && version == b.version && codec == b.codec;
58 // static
59 scoped_ptr<SessionConfig> SessionConfig::SelectCommon(
60 const CandidateSessionConfig* client_config,
61 const CandidateSessionConfig* host_config) {
62 scoped_ptr<SessionConfig> result(new SessionConfig());
63 ChannelConfig control_config;
64 ChannelConfig event_config;
65 ChannelConfig video_config;
66 ChannelConfig audio_config;
68 DCHECK(host_config->standard_ice());
70 // Reject connection if the peer doesn't support ICE.
71 if (!client_config->standard_ice())
72 return nullptr;
74 if (!SelectCommonChannelConfig(host_config->control_configs(),
75 client_config->control_configs(),
76 &result->control_config_) ||
77 !SelectCommonChannelConfig(host_config->event_configs(),
78 client_config->event_configs(),
79 &result->event_config_) ||
80 !SelectCommonChannelConfig(host_config->video_configs(),
81 client_config->video_configs(),
82 &result->video_config_) ||
83 !SelectCommonChannelConfig(host_config->audio_configs(),
84 client_config->audio_configs(),
85 &result->audio_config_)) {
86 return nullptr;
89 return result;
92 // static
93 scoped_ptr<SessionConfig> SessionConfig::GetFinalConfig(
94 const CandidateSessionConfig* candidate_config) {
95 if (candidate_config->control_configs().size() != 1 ||
96 candidate_config->event_configs().size() != 1 ||
97 candidate_config->video_configs().size() != 1 ||
98 candidate_config->audio_configs().size() != 1) {
99 return nullptr;
102 scoped_ptr<SessionConfig> result(new SessionConfig());
103 result->standard_ice_ = candidate_config->standard_ice();
104 result->control_config_ = candidate_config->control_configs().front();
105 result->event_config_ = candidate_config->event_configs().front();
106 result->video_config_ = candidate_config->video_configs().front();
107 result->audio_config_ = candidate_config->audio_configs().front();
109 return result.Pass();
112 // static
113 scoped_ptr<SessionConfig> SessionConfig::ForTest() {
114 scoped_ptr<SessionConfig> result(new SessionConfig());
115 result->control_config_ = ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
116 kControlStreamVersion,
117 ChannelConfig::CODEC_UNDEFINED);
118 result->event_config_ = ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
119 kDefaultStreamVersion,
120 ChannelConfig::CODEC_UNDEFINED);
121 result->video_config_ = ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
122 kDefaultStreamVersion,
123 ChannelConfig::CODEC_VP8);
124 result->audio_config_ = ChannelConfig(ChannelConfig::TRANSPORT_NONE,
125 kDefaultStreamVersion,
126 ChannelConfig::CODEC_UNDEFINED);
127 return result.Pass();
130 SessionConfig::SessionConfig() {
133 CandidateSessionConfig::CandidateSessionConfig() { }
135 CandidateSessionConfig::CandidateSessionConfig(
136 const CandidateSessionConfig& config) = default;
138 CandidateSessionConfig::~CandidateSessionConfig() { }
140 bool CandidateSessionConfig::IsSupported(const SessionConfig& config) const {
141 return config.standard_ice() &&
142 IsChannelConfigSupported(control_configs_, config.control_config()) &&
143 IsChannelConfigSupported(event_configs_, config.event_config()) &&
144 IsChannelConfigSupported(video_configs_, config.video_config()) &&
145 IsChannelConfigSupported(audio_configs_, config.audio_config());
148 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::Clone() const {
149 return make_scoped_ptr(new CandidateSessionConfig(*this));
152 // static
153 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateEmpty() {
154 return make_scoped_ptr(new CandidateSessionConfig());
157 // static
158 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateFrom(
159 const SessionConfig& config) {
160 scoped_ptr<CandidateSessionConfig> result = CreateEmpty();
161 result->set_standard_ice(config.standard_ice());
162 result->mutable_control_configs()->push_back(config.control_config());
163 result->mutable_event_configs()->push_back(config.event_config());
164 result->mutable_video_configs()->push_back(config.video_config());
165 result->mutable_audio_configs()->push_back(config.audio_config());
166 return result.Pass();
169 // static
170 scoped_ptr<CandidateSessionConfig> CandidateSessionConfig::CreateDefault() {
171 scoped_ptr<CandidateSessionConfig> result = CreateEmpty();
173 // Control channel.
174 result->mutable_control_configs()->push_back(
175 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
176 kControlStreamVersion,
177 ChannelConfig::CODEC_UNDEFINED));
179 // Event channel.
180 result->mutable_event_configs()->push_back(
181 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
182 kDefaultStreamVersion,
183 ChannelConfig::CODEC_UNDEFINED));
185 // Video channel.
186 result->mutable_video_configs()->push_back(
187 ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
188 kDefaultStreamVersion,
189 ChannelConfig::CODEC_VP8));
191 // Audio channel.
192 result->mutable_audio_configs()->push_back(
193 ChannelConfig(ChannelConfig::TRANSPORT_MUX_STREAM,
194 kDefaultStreamVersion,
195 ChannelConfig::CODEC_OPUS));
196 result->mutable_audio_configs()->push_back(ChannelConfig::None());
198 return result.Pass();
201 void CandidateSessionConfig::DisableAudioChannel() {
202 mutable_audio_configs()->clear();
203 mutable_audio_configs()->push_back(ChannelConfig());
206 void CandidateSessionConfig::EnableVideoCodec(ChannelConfig::Codec codec) {
207 mutable_video_configs()->push_front(
208 ChannelConfig(ChannelConfig::TRANSPORT_STREAM,
209 kDefaultStreamVersion,
210 codec));
213 } // namespace protocol
214 } // namespace remoting