/*
 * 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/dom/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>);

  // https://w3c.github.io/webrtc-pc/#process-remote-track-addition
  void ProcessAdditionOfRemoteTrack(
      RTCRtpTransceiver* transceiver,
      const WebVector<WebString>& stream_ids,
      HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
          add_list,
      HeapVector<Member<RTCRtpTransceiver>>* track_events);
  // https://w3c.github.io/webrtc-pc/#process-remote-track-removal
  void ProcessRemovalOfRemoteTrack(
      RTCRtpTransceiver* transceiver,
      HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
          remove_list,
      HeapVector<Member<MediaStreamTrack>>* mute_tracks);
  // 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_
