Modified PeerConnection and WebRtcSession for end-to-end QuicDataChannel usage.

To allow end-to-end QuicDataChannel usage with a
PeerConnection, RTCConfiguration has been modified to
include a boolean for whether to do QUIC, since negotiation of
QUIC is not implemented. If one peer does QUIC, then it will be
assumed that the other peer must do QUIC or the connection
will fail.

PeerConnection has been modified to create data channels of type
QuicDataChannel when the peer wants to do QUIC.

WebRtcSession has ben modified to use a QuicDataTransport
instead of a DtlsTransportChannelWrapper/DataChannel
when QUIC should be used

QuicDataTransport implements the generic functions of
BaseChannel to manage the QuicTransportChannel.

Review-Url: https://codereview.webrtc.org/2166873002
Cr-Commit-Position: refs/heads/master@{#13645}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index 4ccd6e8..95cd7ea 100644
--- a/webrtc/api/peerconnection.cc
+++ b/webrtc/api/peerconnection.cc
@@ -907,6 +907,23 @@
     const std::string& label,
     const DataChannelInit* config) {
   TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
+#ifdef HAVE_QUIC
+  if (session_->data_channel_type() == cricket::DCT_QUIC) {
+    // TODO(zhihuang): Handle case when config is NULL.
+    if (!config) {
+      LOG(LS_ERROR) << "Missing config for QUIC data channel.";
+      return nullptr;
+    }
+    // TODO(zhihuang): Allow unreliable or ordered QUIC data channels.
+    if (!config->reliable || config->ordered) {
+      LOG(LS_ERROR) << "QUIC data channel does not implement unreliable or "
+                       "ordered delivery.";
+      return nullptr;
+    }
+    return session_->quic_data_transport()->CreateDataChannel(label, config);
+  }
+#endif  // HAVE_QUIC
+
   bool first_datachannel = !HasDataChannels();
 
   std::unique_ptr<InternalDataChannelInit> internal_config;
@@ -1618,8 +1635,8 @@
       (session_options->has_audio() || session_options->has_video() ||
        session_options->has_data());
 
-  if (session_->data_channel_type() == cricket::DCT_SCTP && HasDataChannels()) {
-    session_options->data_channel_type = cricket::DCT_SCTP;
+  if (HasDataChannels()) {
+    session_options->data_channel_type = session_->data_channel_type();
   }
 
   session_options->rtcp_cname = rtcp_cname_;
@@ -1648,9 +1665,7 @@
   // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams
   // are not signaled in the SDP so does not go through that path and must be
   // handled here.
-  if (session_->data_channel_type() == cricket::DCT_SCTP) {
-    session_options->data_channel_type = cricket::DCT_SCTP;
-  }
+  session_options->data_channel_type = session_->data_channel_type();
   session_options->crypto_options = factory_->options().crypto_options;
 }
 
@@ -2054,7 +2069,13 @@
 }
 
 bool PeerConnection::HasDataChannels() const {
+#ifdef HAVE_QUIC
+  return !rtp_data_channels_.empty() || !sctp_data_channels_.empty() ||
+         (session_->quic_data_transport() &&
+          session_->quic_data_transport()->HasDataChannels());
+#else
   return !rtp_data_channels_.empty() || !sctp_data_channels_.empty();
+#endif  // HAVE_QUIC
 }
 
 void PeerConnection::AllocateSctpSids(rtc::SSLRole role) {