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.

Committed: https://crrev.com/34b54c36a533dadb6ceb70795119194e6f530ef5
Review-Url: https://codereview.webrtc.org/2166873002
Cr-Original-Commit-Position: refs/heads/master@{#13645}
Cr-Commit-Position: refs/heads/master@{#13657}
diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc
index 4ccd6e8..c675015 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,13 @@
       (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;
+  // Intentionally unset the data channel type for RTP data channel with the
+  // second condition. Otherwise the RTP data channels would be successfully
+  // negotiated by default and the unit tests in WebRtcDataBrowserTest will fail
+  // when building with chromium. We want to leave RTP data channels broken, so
+  // people won't try to use them.
+  if (HasDataChannels() && session_->data_channel_type() != cricket::DCT_RTP) {
+    session_options->data_channel_type = session_->data_channel_type();
   }
 
   session_options->rtcp_cname = rtcp_cname_;
@@ -1648,8 +1670,12 @@
   // 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;
+  // Intentionally unset the data channel type for RTP data channel. Otherwise
+  // the RTP data channels would be successfully negotiated by default and the
+  // unit tests in WebRtcDataBrowserTest will fail when building with chromium.
+  // We want to leave RTP data channels broken, so people won't try to use them.
+  if (session_->data_channel_type() != cricket::DCT_RTP) {
+    session_options->data_channel_type = session_->data_channel_type();
   }
   session_options->crypto_options = factory_->options().crypto_options;
 }
@@ -2054,7 +2080,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) {