/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer
 *    in the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of Google Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_PEER_CONNECTION_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_PEER_CONNECTION_H_

#include <memory>
#include <utility>
#include <vector>

#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/crypto/normalize_algorithm.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_enums.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_request.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"

namespace blink {

class ExceptionState;
class MediaStreamTrack;
class MediaStreamTrackOrString;
class RTCAnswerOptions;
class RTCConfiguration;
class RTCDtlsTransport;
class RTCDTMFSender;
class RTCDataChannel;
class RTCDataChannelInit;
class RTCIceCandidateInitOrRTCIceCandidate;
class RTCOfferOptions;
class RTCPeerConnectionTest;
class RTCRtpReceiver;
class RTCRtpSender;
class RTCRtpTransceiverInit;
class RTCSessionDescription;
class RTCSessionDescriptionInit;
class ScriptState;
class V8RTCPeerConnectionErrorCallback;
class V8RTCSessionDescriptionCallback;
class V8RTCStatsCallback;
class V8VoidFunction;

// This enum is used to track usage of SDP during the transition of the default
// "sdpSemantics" value from "Plan B" to "Unified Plan". Usage refers to
// operations such as createOffer(), createAnswer(), setLocalDescription() and
// setRemoteDescription(). "Complex" SDP refers to SDP that is not compatible
// between SDP formats. Usage of SDP falls into two categories: "safe" and
// "unsafe". Applications with unsafe usage are predicted to break when the
// default changes. This includes complex SDP usage and relying on the default
// sdpSemantics. kUnknown is used if the SDP format could not be deduced, such
// as if SDP could not be parsed.
enum class SdpUsageCategory {
  kSafe = 0,
  kUnsafe = 1,
  kUnknown = 2,
  kMaxValue = kUnknown,
};

MODULES_EXPORT SdpUsageCategory
DeduceSdpUsageCategory(const String& sdp_type,
                       const String& sdp,
                       bool sdp_semantics_specified,
                       webrtc::SdpSemantics sdp_semantics);

class MODULES_EXPORT RTCPeerConnection final
    : public EventTargetWithInlineData,
      public WebRTCPeerConnectionHandlerClient,
      public ActiveScriptWrappable<RTCPeerConnection>,
      public ContextLifecycleObserver,
      public MediaStreamObserver {
  DEFINE_WRAPPERTYPEINFO();
  USING_GARBAGE_COLLECTED_MIXIN(RTCPeerConnection);
  USING_PRE_FINALIZER(RTCPeerConnection, Dispose);

 public:
  static RTCPeerConnection* Create(ExecutionContext*,
                                   const RTCConfiguration*,
                                   const Dictionary&,
                                   ExceptionState&);

  RTCPeerConnection(ExecutionContext*,
                    webrtc::PeerConnectionInterface::RTCConfiguration,
                    bool sdp_semantics_specified,
                    WebMediaConstraints,
                    ExceptionState&);
  ~RTCPeerConnection() override;

  ScriptPromise createOffer(ScriptState*, const RTCOfferOptions*);
  ScriptPromise createOffer(ScriptState*,
                            V8RTCSessionDescriptionCallback*,
                            V8RTCPeerConnectionErrorCallback*,
                            const Dictionary&,
                            ExceptionState&);

  ScriptPromise createAnswer(ScriptState*, const RTCAnswerOptions*);
  ScriptPromise createAnswer(ScriptState*,
                             V8RTCSessionDescriptionCallback*,
                             V8RTCPeerConnectionErrorCallback*,
                             const Dictionary&);

  ScriptPromise setLocalDescription(ScriptState*,
                                    const RTCSessionDescriptionInit*);
  ScriptPromise setLocalDescription(
      ScriptState*,
      const RTCSessionDescriptionInit*,
      V8VoidFunction*,
      V8RTCPeerConnectionErrorCallback* = nullptr);
  RTCSessionDescription* localDescription();
  RTCSessionDescription* currentLocalDescription();
  RTCSessionDescription* pendingLocalDescription();

  ScriptPromise setRemoteDescription(ScriptState*,
                                     const RTCSessionDescriptionInit*);
  ScriptPromise setRemoteDescription(
      ScriptState*,
      const RTCSessionDescriptionInit*,
      V8VoidFunction*,
      V8RTCPeerConnectionErrorCallback* = nullptr);
  RTCSessionDescription* remoteDescription();
  RTCSessionDescription* currentRemoteDescription();
  RTCSessionDescription* pendingRemoteDescription();

  String signalingState() const;

  RTCConfiguration* getConfiguration(ScriptState*) const;
  void setConfiguration(ScriptState*, const RTCConfiguration*, ExceptionState&);

  // Certificate management
  // http://w3c.github.io/webrtc-pc/#sec.cert-mgmt
  static ScriptPromise generateCertificate(
      ScriptState*,
      const AlgorithmIdentifier& keygen_algorithm,
      ExceptionState&);

  ScriptPromise addIceCandidate(ScriptState*,
                                const RTCIceCandidateInitOrRTCIceCandidate&,
                                ExceptionState&);
  ScriptPromise addIceCandidate(ScriptState*,
                                const RTCIceCandidateInitOrRTCIceCandidate&,
                                V8VoidFunction*,
                                V8RTCPeerConnectionErrorCallback*,
                                ExceptionState&);

  String iceGatheringState() const;

  String iceConnectionState() const;

  String connectionState() const;

  // A local stream is any stream associated with a sender.
  MediaStreamVector getLocalStreams() const;
  // A remote stream is any stream associated with a receiver.
  MediaStreamVector getRemoteStreams() const;
  MediaStream* getRemoteStreamById(const WebString&) const;
  bool IsRemoteStream(MediaStream* stream) const;

  void addStream(ScriptState*,
                 MediaStream*,
                 const Dictionary& media_constraints,
                 ExceptionState&);

  void removeStream(MediaStream*, ExceptionState&);

  String id(ScriptState*) const;

  // Calls one of the below versions (or rejects with an exception) depending on
  // type, see RTCPeerConnection.idl.
  ScriptPromise getStats(ScriptState*, blink::ScriptValue callback_or_selector);
  // Calls LegacyCallbackBasedGetStats().
  ScriptPromise getStats(ScriptState*,
                         V8RTCStatsCallback* success_callback,
                         MediaStreamTrack* selector = nullptr);
  // Calls PromiseBasedGetStats().
  ScriptPromise getStats(ScriptState*, MediaStreamTrack* selector = nullptr);
  ScriptPromise LegacyCallbackBasedGetStats(
      ScriptState*,
      V8RTCStatsCallback* success_callback,
      MediaStreamTrack* selector);
  ScriptPromise PromiseBasedGetStats(ScriptState*, MediaStreamTrack* selector);

  const HeapVector<Member<RTCRtpTransceiver>>& getTransceivers() const;
  const HeapVector<Member<RTCRtpSender>>& getSenders() const;
  const HeapVector<Member<RTCRtpReceiver>>& getReceivers() const;
  RTCRtpTransceiver* addTransceiver(const MediaStreamTrackOrString&,
                                    const RTCRtpTransceiverInit*,
                                    ExceptionState&);
  RTCRtpSender* addTrack(MediaStreamTrack*, MediaStreamVector, ExceptionState&);
  void removeTrack(RTCRtpSender*, ExceptionState&);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(track, kTrack);

  RTCDataChannel* createDataChannel(ScriptState*,
                                    String label,
                                    const RTCDataChannelInit*,
                                    ExceptionState&);

  RTCDTMFSender* createDTMFSender(MediaStreamTrack*, ExceptionState&);

  bool IsClosed() { return closed_; }
  void close();

  // Makes the peer connection aware of the track. This is used to map web
  // tracks to blink tracks, as is necessary for plumbing. There is no need to
  // unregister the track because Weak references are used.
  void RegisterTrack(MediaStreamTrack*);

  // We allow getStats after close, but not other calls or callbacks.
  bool ShouldFireDefaultCallbacks() { return !closed_ && !stopped_; }
  bool ShouldFireGetStatsCallback() { return !stopped_; }

  DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded, kNegotiationneeded);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(signalingstatechange, kSignalingstatechange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(addstream, kAddstream);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(removestream, kRemovestream);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(iceconnectionstatechange,
                                  kIceconnectionstatechange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionstatechange,
                                  kConnectionstatechange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(icegatheringstatechange,
                                  kIcegatheringstatechange);
  DEFINE_ATTRIBUTE_EVENT_LISTENER(datachannel, kDatachannel);

  // Utility to note result of CreateOffer / CreateAnswer
  void NoteSdpCreated(const RTCSessionDescription&);
  // Utility to report SDP usage of setLocalDescription / setRemoteDescription.
  enum class SetSdpOperationType {
    kSetLocalDescription,
    kSetRemoteDescription,
  };
  void ReportSetSdpUsage(
      SetSdpOperationType operation_type,
      const RTCSessionDescriptionInit* session_description_init) const;

  // MediaStreamObserver
  void OnStreamAddTrack(MediaStream*, MediaStreamTrack*) override;
  void OnStreamRemoveTrack(MediaStream*, MediaStreamTrack*) override;

  // WebRTCPeerConnectionHandlerClient
  void NegotiationNeeded() override;
  void DidGenerateICECandidate(scoped_refptr<WebRTCICECandidate>) override;
  void DidChangeSignalingState(
      webrtc::PeerConnectionInterface::SignalingState) override;
  void DidChangeIceGatheringState(
      webrtc::PeerConnectionInterface::IceGatheringState) override;
  void DidChangeIceConnectionState(
      webrtc::PeerConnectionInterface::IceConnectionState) override;
  void DidChangePeerConnectionState(
      webrtc::PeerConnectionInterface::PeerConnectionState) override;
  void DidAddReceiverPlanB(std::unique_ptr<WebRTCRtpReceiver>) override;
  void DidRemoveReceiverPlanB(std::unique_ptr<WebRTCRtpReceiver>) override;
  void DidModifyTransceivers(std::vector<std::unique_ptr<WebRTCRtpTransceiver>>,
                             bool is_remote_description) override;
  void DidAddRemoteDataChannel(WebRTCDataChannelHandler*) override;
  void DidNoteInterestingUsage(int usage_pattern) override;
  void ReleasePeerConnectionHandler() override;
  void ClosePeerConnection() override;

  // EventTarget
  const AtomicString& InterfaceName() const override;
  ExecutionContext* GetExecutionContext() const override;

  // ContextLifecycleObserver
  void ContextDestroyed(ExecutionContext*) override;

  // ScriptWrappable
  // We keep the this object alive until either stopped or closed.
  bool HasPendingActivity() const final { return !closed_ && !stopped_; }

  // For testing; exported to testing/InternalWebRTCPeerConnection
  static int PeerConnectionCount();
  static int PeerConnectionCountLimit();

  // SLD/SRD Helper method, public for testing.
  // This function returns a value that indicates if complex SDP is being used
  // and whether a format is explicitly specified. If the SDP is not complex or
  // it could not be parsed, base::nullopt is returned.
  // When "Complex" SDP (i.e., SDP that has multiple tracks) is used without
  // explicitly specifying the SDP format, there may be errors if the
  // application assumes a format that differs from the actual default format.
  base::Optional<ComplexSdpCategory> CheckForComplexSdp(
      const RTCSessionDescriptionInit* session_description_init) const;

  const CallSetupStateTracker& call_setup_state_tracker() const;
  void NoteCallSetupStateEventPending(
      RTCPeerConnection::SetSdpOperationType operation,
      const RTCSessionDescriptionInit& description);
  void NoteSessionDescriptionRequestCompleted(
      RTCCreateSessionDescriptionOperation operation,
      bool success);
  void NoteVoidRequestCompleted(RTCSetSessionDescriptionOperation operation,
                                bool success);
  // Checks if the document that the peer connection lives in has ever executed
  // getUserMedia().
  bool HasDocumentMedia() const;

  // Look up, and potentially create, a DTLSTransport object.
  RTCDtlsTransport* LookupDtlsTransportByMid(String mid);
  void Trace(blink::Visitor*) override;

 private:
  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioTrack);
  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetVideoTrack);
  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioAndVideoTrack);
  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetTrackRemoveStreamAndGCAll);
  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest,
                           GetTrackRemoveStreamAndGCWithPersistentComponent);
  FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest,
                           GetTrackRemoveStreamAndGCWithPersistentStream);

  typedef base::OnceCallback<bool()> BoolFunction;
  class EventWrapper : public GarbageCollectedFinalized<EventWrapper> {
   public:
    EventWrapper(Event*, BoolFunction);
    // Returns true if |m_setupFunction| returns true or it is null.
    // |m_event| will only be fired if setup() returns true;
    bool Setup();

    void Trace(blink::Visitor*);

    Member<Event> event_;

   private:
    BoolFunction setup_function_;
  };
  void Dispose();

  void ScheduleDispatchEvent(Event*);
  void ScheduleDispatchEvent(Event*, BoolFunction);
  void DispatchScheduledEvents();
  void MaybeFireNegotiationNeeded();
  MediaStreamTrack* GetTrack(const WebMediaStreamTrack&) const;
  RTCRtpSender* FindSenderForTrackAndStream(MediaStreamTrack*, MediaStream*);
  HeapVector<Member<RTCRtpSender>>::iterator FindSender(
      const WebRTCRtpSender& web_sender);
  HeapVector<Member<RTCRtpReceiver>>::iterator FindReceiver(
      const WebRTCRtpReceiver& web_receiver);
  HeapVector<Member<RTCRtpTransceiver>>::iterator FindTransceiver(
      const WebRTCRtpTransceiver& web_transceiver);

  // Creates or updates the sender such that it is up-to-date with the
  // WebRTCRtpSender in all regards *except for streams*. The web sender only
  // knows of stream IDs; updating the stream objects requires additional logic
  // which is different depending on context, e.g:
  // - If created/updated with addTrack(), the streams were supplied as
  //   arguments.
  // The web sender's web track must already have a correspondent blink track in
  // |tracks_|. The caller is responsible for ensuring this with
  // RegisterTrack(), e.g:
  // - On addTrack(), the track is supplied as an argument.
  RTCRtpSender* CreateOrUpdateSender(std::unique_ptr<WebRTCRtpSender>,
                                     String kind);
  // Creates or updates the receiver such that it is up-to-date with the
  // WebRTCRtpReceiver in all regards *except for streams*. The web receiver
  // only knows of stream IDs; updating the stream objects requires additional
  // logic which is different depending on context, e.g:
  // - If created/updated with setRemoteDescription(), there is an algorithm for
  //   processing the addition/removal of remote tracks which includes how to
  //   create and update the associated streams set.
  RTCRtpReceiver* CreateOrUpdateReceiver(std::unique_ptr<WebRTCRtpReceiver>);
  // Creates or updates the transceiver such that it, including its sender and
  // receiver, are up-to-date with the WebRTCRtpTransceiver in all regerds
  // *except for sender and receiver streams*. The web sender and web receiver
  // only knows of stream IDs; updating the stream objects require additional
  // logic which is different depending on context. See above.
  RTCRtpTransceiver* CreateOrUpdateTransceiver(
      std::unique_ptr<WebRTCRtpTransceiver>);

  // Update the |receiver->streams()| to the streams indicated by |stream_ids|,
  // adding to |remove_list| and |add_list| accordingly.
  // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams
  void SetAssociatedMediaStreams(
      RTCRtpReceiver* receiver,
      const WebVector<WebString>& stream_ids,
      HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
          remove_list,
      HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
          add_list);

  // Sets the signaling state synchronously, and dispatches a
  // signalingstatechange event synchronously or asynchronously depending on
  // |dispatch_event_immediately|.
  // TODO(hbos): The ability to not fire the event asynchronously is there
  // because CloseInternal() has historically fired asynchronously along with
  // other asynchronously fired events. If close() does not fire any events,
  // |dispatch_event_immediately| can be removed. https://crbug.com/849247
  void ChangeSignalingState(webrtc::PeerConnectionInterface::SignalingState,
                            bool dispatch_event_immediately);
  // The remaining "Change" methods set the state asynchronously and fire the
  // corresponding event immediately after changing the state (if it was really
  // changed).
  //
  // The "Set" methods are called asynchronously by the "Change" methods, and
  // set the corresponding state without firing an event, returning true if the
  // state was really changed.
  //
  // This is done because the standard guarantees that state changes and the
  // corresponding events will happen in the same task; it shouldn't be
  // possible to, for example, end up with two "icegatheringstatechange" events
  // that are delayed somehow and cause the application to read a "complete"
  // gathering state twice, missing the "gathering" state in the middle.
  void ChangeIceGatheringState(
      webrtc::PeerConnectionInterface::IceGatheringState);
  bool SetIceGatheringState(webrtc::PeerConnectionInterface::IceGatheringState);

  void ChangeIceConnectionState(
      webrtc::PeerConnectionInterface::IceConnectionState);
  bool SetIceConnectionState(
      webrtc::PeerConnectionInterface::IceConnectionState);

  void ChangePeerConnectionState(
      webrtc::PeerConnectionInterface::PeerConnectionState);
  bool SetPeerConnectionState(
      webrtc::PeerConnectionInterface::PeerConnectionState);

  void CloseInternal();

  void RecordRapporMetrics();

  DOMException* checkSdpForStateErrors(ExecutionContext*,
                                       const RTCSessionDescriptionInit*,
                                       String* sdp);
  void MaybeWarnAboutUnsafeSdp(
      const RTCSessionDescriptionInit* session_description_init) const;

  webrtc::PeerConnectionInterface::SignalingState signaling_state_;
  webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state_;
  webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state_;
  webrtc::PeerConnectionInterface::PeerConnectionState peer_connection_state_;
  CallSetupStateTracker call_setup_state_tracker_;

  // A map containing any track that is in use by the peer connection. This
  // includes tracks of |rtp_senders_| and |rtp_receivers_|.
  HeapHashMap<WeakMember<MediaStreamComponent>, WeakMember<MediaStreamTrack>>
      tracks_;
  // In Plan B, senders and receivers exist independently of one another.
  // In Unified Plan, all senders and receivers are the sender-receiver pairs of
  // transceivers.
  // TODO(hbos): When Plan B is removed, remove |rtp_senders_| and
  // |rtp_receivers_| since these are part of |transceivers_|.
  // https://crbug.com/857004
  HeapVector<Member<RTCRtpSender>> rtp_senders_;
  HeapVector<Member<RTCRtpReceiver>> rtp_receivers_;
  HeapVector<Member<RTCRtpTransceiver>> transceivers_;

  // A map of all transports that have been looked up by MID.
  // A transport may be referenced by more than one mid, so may
  // be present multiple times in the table.
  HeapHashMap<String, Member<RTCDtlsTransport>> dtls_transports_by_mid_;

  std::unique_ptr<WebRTCPeerConnectionHandler> peer_handler_;

  TaskHandle dispatch_scheduled_events_task_handle_;
  HeapVector<Member<EventWrapper>> scheduled_events_;

  // This handle notifies scheduler about an active connection associated
  // with a frame. Handle should be destroyed when connection is closed.
  std::unique_ptr<FrameScheduler::ActiveConnectionHandle>
      connection_handle_for_scheduler_;

  bool negotiation_needed_;
  bool stopped_;
  bool closed_;

  // Internal state [[LastOffer]] and [[LastAnswer]]
  String last_offer_;
  String last_answer_;

  bool has_data_channels_;  // For RAPPOR metrics
  // In Plan B, senders and receivers are added or removed independently of one
  // another. In Unified Plan, senders and receivers are created in pairs as
  // transceivers. Transceivers may become inactive, but are never removed.
  // The value of this member affects the behavior of some methods and what
  // information is surfaced from webrtc. This has the value "kPlanB" or
  // "kUnifiedPlan", if constructed with "kDefault" it is translated to one or
  // the other.
  webrtc::SdpSemantics sdp_semantics_;
  // Whether sdpSemantics was specified at construction.
  bool sdp_semantics_specified_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_PEER_CONNECTION_H_
