// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef REMOTING_PROTOCOL_SESSION_CONFIG_H_ #define REMOTING_PROTOCOL_SESSION_CONFIG_H_ #include #include #include "base/memory/scoped_ptr.h" namespace remoting { namespace protocol { extern const int kDefaultStreamVersion; // Struct for configuration parameters of a single channel. // Some channels (like video) may have multiple underlying sockets that need // to be configured simultaneously. struct ChannelConfig { enum TransportType { TRANSPORT_STREAM, TRANSPORT_MUX_STREAM, TRANSPORT_DATAGRAM, TRANSPORT_NONE, }; enum Codec { CODEC_UNDEFINED, // Used for event and control channels. CODEC_VERBATIM, CODEC_ZIP, CODEC_VP8, CODEC_VP9, CODEC_OPUS, CODEC_SPEEX, }; // Creates a config with transport field set to TRANSPORT_NONE which indicates // that corresponding channel is disabled. static ChannelConfig None(); // Default constructor. Equivalent to None(). ChannelConfig() = default; // Creates a channel config with the specified parameters. ChannelConfig(TransportType transport, int version, Codec codec); // operator== is overloaded so that std::find() works with // std::list. bool operator==(const ChannelConfig& b) const; TransportType transport = TRANSPORT_NONE; int version = 0; Codec codec = CODEC_UNDEFINED; }; class CandidateSessionConfig; // SessionConfig is used to represent negotiated session configuration. Note // that it's useful mainly for the legacy protocol. When using the new // WebRTC-based protocol the using_webrtc() flag is set to true and all other // fields should be ignored. class SessionConfig { public: enum class Protocol { // Current ICE-based protocol. ICE, // New WebRTC-based protocol. WEBRTC, }; // Selects session configuration that is supported by both participants. // nullptr is returned if such configuration doesn't exist. When selecting // channel configuration priority is given to the configs listed first // in |client_config|. static scoped_ptr SelectCommon( const CandidateSessionConfig* client_config, const CandidateSessionConfig* host_config); // Extracts final protocol configuration. Must be used for the description // received in the session-accept stanza. If the selection is ambiguous // (e.g. there is more than one configuration for one of the channel) // or undefined (e.g. no configurations for a channel) then nullptr is // returned. static scoped_ptr GetFinalConfig( const CandidateSessionConfig* candidate_config); // Returns a suitable session configuration for use in tests. static scoped_ptr ForTest(); static scoped_ptr ForTestWithVerbatimVideo(); static scoped_ptr ForTestWithWebrtc(); Protocol protocol() const { return protocol_; } // All fields below should be ignored when protocol() is set to WEBRTC. const ChannelConfig& control_config() const; const ChannelConfig& event_config() const; const ChannelConfig& video_config() const; const ChannelConfig& audio_config() const; bool is_audio_enabled() const { return audio_config_.transport != ChannelConfig::TRANSPORT_NONE; } private: SessionConfig(Protocol protocol); const Protocol protocol_; ChannelConfig control_config_; ChannelConfig event_config_; ChannelConfig video_config_; ChannelConfig audio_config_; }; // Defines session description that is sent from client to the host in the // session-initiate message. It is different from the regular Config // because it allows one to specify multiple configurations for each channel. class CandidateSessionConfig { public: static scoped_ptr CreateEmpty(); static scoped_ptr CreateFrom( const SessionConfig& config); static scoped_ptr CreateDefault(); ~CandidateSessionConfig(); bool webrtc_supported() const { return webrtc_supported_; } void set_webrtc_supported(bool webrtc_supported) { webrtc_supported_ = webrtc_supported; } bool ice_supported() const { return ice_supported_; } void set_ice_supported(bool ice_supported) { ice_supported_ = ice_supported; } const std::list& control_configs() const { return control_configs_; } std::list* mutable_control_configs() { return &control_configs_; } const std::list& event_configs() const { return event_configs_; } std::list* mutable_event_configs() { return &event_configs_; } const std::list& video_configs() const { return video_configs_; } std::list* mutable_video_configs() { return &video_configs_; } const std::list& audio_configs() const { return audio_configs_; } std::list* mutable_audio_configs() { return &audio_configs_; } // Old clients always list VP9 as supported and preferred even though they // shouldn't have it enabled yet. I.e. the host cannot trust VP9 codec // preference received from the client. To workaround this issue the client // adds a hint in the session-initiate message to indicate that it actually // wants VP9 to be enabled. // // TODO(sergeyu): Remove this kludge as soon as VP9 is enabled by default. bool vp9_experiment_enabled() const { return vp9_experiment_enabled_; } void set_vp9_experiment_enabled(bool value) { vp9_experiment_enabled_ = value; } // Returns true if |config| is supported. bool IsSupported(const SessionConfig& config) const; scoped_ptr Clone() const; // Helpers for enabling/disabling specific features. void DisableAudioChannel(); void PreferTransport(ChannelConfig::TransportType transport); private: CandidateSessionConfig(); explicit CandidateSessionConfig(const CandidateSessionConfig& config); CandidateSessionConfig& operator=(const CandidateSessionConfig& b); bool webrtc_supported_ = false; bool ice_supported_ = false; std::list control_configs_; std::list event_configs_; std::list video_configs_; std::list audio_configs_; bool vp9_experiment_enabled_ = false; }; } // namespace protocol } // namespace remoting #endif // REMOTING_PROTOCOL_SESSION_CONFIG_H_