| OLD | NEW | 
 | (Empty) | 
|    1 /* |  | 
|    2  *  Copyright 2009 The WebRTC Project Authors. All rights reserved. |  | 
|    3  * |  | 
|    4  *  Use of this source code is governed by a BSD-style license |  | 
|    5  *  that can be found in the LICENSE file in the root of the source |  | 
|    6  *  tree. An additional intellectual property rights grant can be found |  | 
|    7  *  in the file PATENTS.  All contributing project authors may |  | 
|    8  *  be found in the AUTHORS file in the root of the source tree. |  | 
|    9  */ |  | 
|   10  |  | 
|   11 #ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |  | 
|   12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |  | 
|   13  |  | 
|   14 #include <map> |  | 
|   15 #include <string> |  | 
|   16 #include <vector> |  | 
|   17  |  | 
|   18 #include "webrtc/p2p/base/transport.h" |  | 
|   19 #include "webrtc/p2p/base/transportchannel.h" |  | 
|   20 #include "webrtc/p2p/base/transportcontroller.h" |  | 
|   21 #include "webrtc/p2p/base/transportchannelimpl.h" |  | 
|   22 #include "webrtc/base/bind.h" |  | 
|   23 #include "webrtc/base/buffer.h" |  | 
|   24 #include "webrtc/base/fakesslidentity.h" |  | 
|   25 #include "webrtc/base/messagequeue.h" |  | 
|   26 #include "webrtc/base/sigslot.h" |  | 
|   27 #include "webrtc/base/sslfingerprint.h" |  | 
|   28 #include "webrtc/base/thread.h" |  | 
|   29  |  | 
|   30 namespace cricket { |  | 
|   31  |  | 
|   32 class FakeTransport; |  | 
|   33  |  | 
|   34 struct PacketMessageData : public rtc::MessageData { |  | 
|   35   PacketMessageData(const char* data, size_t len) : packet(data, len) {} |  | 
|   36   rtc::Buffer packet; |  | 
|   37 }; |  | 
|   38  |  | 
|   39 // Fake transport channel class, which can be passed to anything that needs a |  | 
|   40 // transport channel. Can be informed of another FakeTransportChannel via |  | 
|   41 // SetDestination. |  | 
|   42 // TODO(hbos): Move implementation to .cc file, this and other classes in file. |  | 
|   43 class FakeTransportChannel : public TransportChannelImpl, |  | 
|   44                              public rtc::MessageHandler { |  | 
|   45  public: |  | 
|   46   explicit FakeTransportChannel(Transport* transport, |  | 
|   47                                 const std::string& name, |  | 
|   48                                 int component) |  | 
|   49       : TransportChannelImpl(name, component), |  | 
|   50         transport_(transport), |  | 
|   51         dtls_fingerprint_("", nullptr, 0) {} |  | 
|   52   ~FakeTransportChannel() { Reset(); } |  | 
|   53  |  | 
|   54   uint64 IceTiebreaker() const { return tiebreaker_; } |  | 
|   55   IceMode remote_ice_mode() const { return remote_ice_mode_; } |  | 
|   56   const std::string& ice_ufrag() const { return ice_ufrag_; } |  | 
|   57   const std::string& ice_pwd() const { return ice_pwd_; } |  | 
|   58   const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; } |  | 
|   59   const std::string& remote_ice_pwd() const { return remote_ice_pwd_; } |  | 
|   60   const rtc::SSLFingerprint& dtls_fingerprint() const { |  | 
|   61     return dtls_fingerprint_; |  | 
|   62   } |  | 
|   63  |  | 
|   64   // If async, will send packets by "Post"-ing to message queue instead of |  | 
|   65   // synchronously "Send"-ing. |  | 
|   66   void SetAsync(bool async) { async_ = async; } |  | 
|   67  |  | 
|   68   Transport* GetTransport() override { return transport_; } |  | 
|   69  |  | 
|   70   TransportChannelState GetState() const override { |  | 
|   71     if (connection_count_ == 0) { |  | 
|   72       return had_connection_ ? TransportChannelState::STATE_FAILED |  | 
|   73                              : TransportChannelState::STATE_INIT; |  | 
|   74     } |  | 
|   75  |  | 
|   76     if (connection_count_ == 1) { |  | 
|   77       return TransportChannelState::STATE_COMPLETED; |  | 
|   78     } |  | 
|   79  |  | 
|   80     return TransportChannelState::STATE_CONNECTING; |  | 
|   81   } |  | 
|   82  |  | 
|   83   void SetIceRole(IceRole role) override { role_ = role; } |  | 
|   84   IceRole GetIceRole() const override { return role_; } |  | 
|   85   void SetIceTiebreaker(uint64 tiebreaker) override { |  | 
|   86     tiebreaker_ = tiebreaker; |  | 
|   87   } |  | 
|   88   void SetIceCredentials(const std::string& ice_ufrag, |  | 
|   89                          const std::string& ice_pwd) override { |  | 
|   90     ice_ufrag_ = ice_ufrag; |  | 
|   91     ice_pwd_ = ice_pwd; |  | 
|   92   } |  | 
|   93   void SetRemoteIceCredentials(const std::string& ice_ufrag, |  | 
|   94                                const std::string& ice_pwd) override { |  | 
|   95     remote_ice_ufrag_ = ice_ufrag; |  | 
|   96     remote_ice_pwd_ = ice_pwd; |  | 
|   97   } |  | 
|   98  |  | 
|   99   void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; } |  | 
|  100   bool SetRemoteFingerprint(const std::string& alg, |  | 
|  101                             const uint8* digest, |  | 
|  102                             size_t digest_len) override { |  | 
|  103     dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len); |  | 
|  104     return true; |  | 
|  105   } |  | 
|  106   bool SetSslRole(rtc::SSLRole role) override { |  | 
|  107     ssl_role_ = role; |  | 
|  108     return true; |  | 
|  109   } |  | 
|  110   bool GetSslRole(rtc::SSLRole* role) const override { |  | 
|  111     *role = ssl_role_; |  | 
|  112     return true; |  | 
|  113   } |  | 
|  114  |  | 
|  115   void Connect() override { |  | 
|  116     if (state_ == STATE_INIT) { |  | 
|  117       state_ = STATE_CONNECTING; |  | 
|  118     } |  | 
|  119   } |  | 
|  120  |  | 
|  121   void MaybeStartGathering() override { |  | 
|  122     if (gathering_state_ == kIceGatheringNew) { |  | 
|  123       gathering_state_ = kIceGatheringGathering; |  | 
|  124       SignalGatheringState(this); |  | 
|  125     } |  | 
|  126   } |  | 
|  127  |  | 
|  128   IceGatheringState gathering_state() const override { |  | 
|  129     return gathering_state_; |  | 
|  130   } |  | 
|  131  |  | 
|  132   void Reset() { |  | 
|  133     if (state_ != STATE_INIT) { |  | 
|  134       state_ = STATE_INIT; |  | 
|  135       if (dest_) { |  | 
|  136         dest_->state_ = STATE_INIT; |  | 
|  137         dest_->dest_ = nullptr; |  | 
|  138         dest_ = nullptr; |  | 
|  139       } |  | 
|  140     } |  | 
|  141   } |  | 
|  142  |  | 
|  143   void SetWritable(bool writable) { set_writable(writable); } |  | 
|  144  |  | 
|  145   void SetDestination(FakeTransportChannel* dest) { |  | 
|  146     if (state_ == STATE_CONNECTING && dest) { |  | 
|  147       // This simulates the delivery of candidates. |  | 
|  148       dest_ = dest; |  | 
|  149       dest_->dest_ = this; |  | 
|  150       if (local_cert_ && dest_->local_cert_) { |  | 
|  151         do_dtls_ = true; |  | 
|  152         dest_->do_dtls_ = true; |  | 
|  153         NegotiateSrtpCiphers(); |  | 
|  154       } |  | 
|  155       state_ = STATE_CONNECTED; |  | 
|  156       dest_->state_ = STATE_CONNECTED; |  | 
|  157       set_writable(true); |  | 
|  158       dest_->set_writable(true); |  | 
|  159     } else if (state_ == STATE_CONNECTED && !dest) { |  | 
|  160       // Simulates loss of connectivity, by asymmetrically forgetting dest_. |  | 
|  161       dest_ = nullptr; |  | 
|  162       state_ = STATE_CONNECTING; |  | 
|  163       set_writable(false); |  | 
|  164     } |  | 
|  165   } |  | 
|  166  |  | 
|  167   void SetConnectionCount(size_t connection_count) { |  | 
|  168     size_t old_connection_count = connection_count_; |  | 
|  169     connection_count_ = connection_count; |  | 
|  170     if (connection_count) |  | 
|  171       had_connection_ = true; |  | 
|  172     if (connection_count_ < old_connection_count) |  | 
|  173       SignalConnectionRemoved(this); |  | 
|  174   } |  | 
|  175  |  | 
|  176   void SetCandidatesGatheringComplete() { |  | 
|  177     if (gathering_state_ != kIceGatheringComplete) { |  | 
|  178       gathering_state_ = kIceGatheringComplete; |  | 
|  179       SignalGatheringState(this); |  | 
|  180     } |  | 
|  181   } |  | 
|  182  |  | 
|  183   void SetReceiving(bool receiving) { set_receiving(receiving); } |  | 
|  184  |  | 
|  185   void SetReceivingTimeout(int timeout) override { |  | 
|  186     receiving_timeout_ = timeout; |  | 
|  187   } |  | 
|  188  |  | 
|  189   int receiving_timeout() const { return receiving_timeout_; } |  | 
|  190  |  | 
|  191   int SendPacket(const char* data, |  | 
|  192                  size_t len, |  | 
|  193                  const rtc::PacketOptions& options, |  | 
|  194                  int flags) override { |  | 
|  195     if (state_ != STATE_CONNECTED) { |  | 
|  196       return -1; |  | 
|  197     } |  | 
|  198  |  | 
|  199     if (flags != PF_SRTP_BYPASS && flags != 0) { |  | 
|  200       return -1; |  | 
|  201     } |  | 
|  202  |  | 
|  203     PacketMessageData* packet = new PacketMessageData(data, len); |  | 
|  204     if (async_) { |  | 
|  205       rtc::Thread::Current()->Post(this, 0, packet); |  | 
|  206     } else { |  | 
|  207       rtc::Thread::Current()->Send(this, 0, packet); |  | 
|  208     } |  | 
|  209     return static_cast<int>(len); |  | 
|  210   } |  | 
|  211   int SetOption(rtc::Socket::Option opt, int value) override { return true; } |  | 
|  212   bool GetOption(rtc::Socket::Option opt, int* value) override { return true; } |  | 
|  213   int GetError() override { return 0; } |  | 
|  214  |  | 
|  215   void AddRemoteCandidate(const Candidate& candidate) override { |  | 
|  216     remote_candidates_.push_back(candidate); |  | 
|  217   } |  | 
|  218   const Candidates& remote_candidates() const { return remote_candidates_; } |  | 
|  219  |  | 
|  220   void OnMessage(rtc::Message* msg) override { |  | 
|  221     PacketMessageData* data = static_cast<PacketMessageData*>(msg->pdata); |  | 
|  222     dest_->SignalReadPacket(dest_, data->packet.data<char>(), |  | 
|  223                             data->packet.size(), rtc::CreatePacketTime(0), 0); |  | 
|  224     delete data; |  | 
|  225   } |  | 
|  226  |  | 
|  227   bool SetLocalCertificate( |  | 
|  228       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |  | 
|  229     local_cert_ = certificate; |  | 
|  230     return true; |  | 
|  231   } |  | 
|  232  |  | 
|  233   void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) { |  | 
|  234     remote_cert_ = cert; |  | 
|  235   } |  | 
|  236  |  | 
|  237   bool IsDtlsActive() const override { return do_dtls_; } |  | 
|  238  |  | 
|  239   bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override { |  | 
|  240     srtp_ciphers_ = ciphers; |  | 
|  241     return true; |  | 
|  242   } |  | 
|  243  |  | 
|  244   bool GetSrtpCipher(std::string* cipher) override { |  | 
|  245     if (!chosen_srtp_cipher_.empty()) { |  | 
|  246       *cipher = chosen_srtp_cipher_; |  | 
|  247       return true; |  | 
|  248     } |  | 
|  249     return false; |  | 
|  250   } |  | 
|  251  |  | 
|  252   bool GetSslCipher(std::string* cipher) override { return false; } |  | 
|  253  |  | 
|  254   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const { |  | 
|  255     return local_cert_; |  | 
|  256   } |  | 
|  257  |  | 
|  258   bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override { |  | 
|  259     if (!remote_cert_) |  | 
|  260       return false; |  | 
|  261  |  | 
|  262     *cert = remote_cert_->GetReference(); |  | 
|  263     return true; |  | 
|  264   } |  | 
|  265  |  | 
|  266   bool ExportKeyingMaterial(const std::string& label, |  | 
|  267                             const uint8* context, |  | 
|  268                             size_t context_len, |  | 
|  269                             bool use_context, |  | 
|  270                             uint8* result, |  | 
|  271                             size_t result_len) override { |  | 
|  272     if (!chosen_srtp_cipher_.empty()) { |  | 
|  273       memset(result, 0xff, result_len); |  | 
|  274       return true; |  | 
|  275     } |  | 
|  276  |  | 
|  277     return false; |  | 
|  278   } |  | 
|  279  |  | 
|  280   void NegotiateSrtpCiphers() { |  | 
|  281     for (std::vector<std::string>::const_iterator it1 = srtp_ciphers_.begin(); |  | 
|  282          it1 != srtp_ciphers_.end(); ++it1) { |  | 
|  283       for (std::vector<std::string>::const_iterator it2 = |  | 
|  284                dest_->srtp_ciphers_.begin(); |  | 
|  285            it2 != dest_->srtp_ciphers_.end(); ++it2) { |  | 
|  286         if (*it1 == *it2) { |  | 
|  287           chosen_srtp_cipher_ = *it1; |  | 
|  288           dest_->chosen_srtp_cipher_ = *it2; |  | 
|  289           return; |  | 
|  290         } |  | 
|  291       } |  | 
|  292     } |  | 
|  293   } |  | 
|  294  |  | 
|  295   bool GetStats(ConnectionInfos* infos) override { |  | 
|  296     ConnectionInfo info; |  | 
|  297     infos->clear(); |  | 
|  298     infos->push_back(info); |  | 
|  299     return true; |  | 
|  300   } |  | 
|  301  |  | 
|  302   void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) { |  | 
|  303     ssl_max_version_ = version; |  | 
|  304   } |  | 
|  305   rtc::SSLProtocolVersion ssl_max_protocol_version() const { |  | 
|  306     return ssl_max_version_; |  | 
|  307   } |  | 
|  308  |  | 
|  309  private: |  | 
|  310   enum State { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED }; |  | 
|  311   Transport* transport_; |  | 
|  312   FakeTransportChannel* dest_ = nullptr; |  | 
|  313   State state_ = STATE_INIT; |  | 
|  314   bool async_ = false; |  | 
|  315   Candidates remote_candidates_; |  | 
|  316   rtc::scoped_refptr<rtc::RTCCertificate> local_cert_; |  | 
|  317   rtc::FakeSSLCertificate* remote_cert_ = nullptr; |  | 
|  318   bool do_dtls_ = false; |  | 
|  319   std::vector<std::string> srtp_ciphers_; |  | 
|  320   std::string chosen_srtp_cipher_; |  | 
|  321   int receiving_timeout_ = -1; |  | 
|  322   IceRole role_ = ICEROLE_UNKNOWN; |  | 
|  323   uint64 tiebreaker_ = 0; |  | 
|  324   std::string ice_ufrag_; |  | 
|  325   std::string ice_pwd_; |  | 
|  326   std::string remote_ice_ufrag_; |  | 
|  327   std::string remote_ice_pwd_; |  | 
|  328   IceMode remote_ice_mode_ = ICEMODE_FULL; |  | 
|  329   rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_10; |  | 
|  330   rtc::SSLFingerprint dtls_fingerprint_; |  | 
|  331   rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; |  | 
|  332   size_t connection_count_ = 0; |  | 
|  333   IceGatheringState gathering_state_ = kIceGatheringNew; |  | 
|  334   bool had_connection_ = false; |  | 
|  335 }; |  | 
|  336  |  | 
|  337 // Fake transport class, which can be passed to anything that needs a Transport. |  | 
|  338 // Can be informed of another FakeTransport via SetDestination (low-tech way |  | 
|  339 // of doing candidates) |  | 
|  340 class FakeTransport : public Transport { |  | 
|  341  public: |  | 
|  342   typedef std::map<int, FakeTransportChannel*> ChannelMap; |  | 
|  343  |  | 
|  344   explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {} |  | 
|  345  |  | 
|  346   // Note that we only have a constructor with the allocator parameter so it can |  | 
|  347   // be wrapped by a DtlsTransport. |  | 
|  348   FakeTransport(const std::string& name, PortAllocator* allocator) |  | 
|  349       : Transport(name, nullptr) {} |  | 
|  350  |  | 
|  351   ~FakeTransport() { DestroyAllChannels(); } |  | 
|  352  |  | 
|  353   const ChannelMap& channels() const { return channels_; } |  | 
|  354  |  | 
|  355   // If async, will send packets by "Post"-ing to message queue instead of |  | 
|  356   // synchronously "Send"-ing. |  | 
|  357   void SetAsync(bool async) { async_ = async; } |  | 
|  358   void SetDestination(FakeTransport* dest) { |  | 
|  359     dest_ = dest; |  | 
|  360     for (const auto& kv : channels_) { |  | 
|  361       kv.second->SetLocalCertificate(certificate_); |  | 
|  362       SetChannelDestination(kv.first, kv.second); |  | 
|  363     } |  | 
|  364   } |  | 
|  365  |  | 
|  366   void SetWritable(bool writable) { |  | 
|  367     for (const auto& kv : channels_) { |  | 
|  368       kv.second->SetWritable(writable); |  | 
|  369     } |  | 
|  370   } |  | 
|  371  |  | 
|  372   void SetLocalCertificate( |  | 
|  373       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override { |  | 
|  374     certificate_ = certificate; |  | 
|  375   } |  | 
|  376   bool GetLocalCertificate( |  | 
|  377       rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override { |  | 
|  378     if (!certificate_) |  | 
|  379       return false; |  | 
|  380  |  | 
|  381     *certificate = certificate_; |  | 
|  382     return true; |  | 
|  383   } |  | 
|  384  |  | 
|  385   bool GetSslRole(rtc::SSLRole* role) const override { |  | 
|  386     if (channels_.empty()) { |  | 
|  387       return false; |  | 
|  388     } |  | 
|  389     return channels_.begin()->second->GetSslRole(role); |  | 
|  390   } |  | 
|  391  |  | 
|  392   bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override { |  | 
|  393     ssl_max_version_ = version; |  | 
|  394     for (const auto& kv : channels_) { |  | 
|  395       kv.second->set_ssl_max_protocol_version(ssl_max_version_); |  | 
|  396     } |  | 
|  397     return true; |  | 
|  398   } |  | 
|  399   rtc::SSLProtocolVersion ssl_max_protocol_version() const { |  | 
|  400     return ssl_max_version_; |  | 
|  401   } |  | 
|  402  |  | 
|  403   using Transport::local_description; |  | 
|  404   using Transport::remote_description; |  | 
|  405  |  | 
|  406  protected: |  | 
|  407   TransportChannelImpl* CreateTransportChannel(int component) override { |  | 
|  408     if (channels_.find(component) != channels_.end()) { |  | 
|  409       return nullptr; |  | 
|  410     } |  | 
|  411     FakeTransportChannel* channel = |  | 
|  412         new FakeTransportChannel(this, name(), component); |  | 
|  413     channel->set_ssl_max_protocol_version(ssl_max_version_); |  | 
|  414     channel->SetAsync(async_); |  | 
|  415     SetChannelDestination(component, channel); |  | 
|  416     channels_[component] = channel; |  | 
|  417     return channel; |  | 
|  418   } |  | 
|  419  |  | 
|  420   void DestroyTransportChannel(TransportChannelImpl* channel) override { |  | 
|  421     channels_.erase(channel->component()); |  | 
|  422     delete channel; |  | 
|  423   } |  | 
|  424  |  | 
|  425  private: |  | 
|  426   FakeTransportChannel* GetFakeChannel(int component) { |  | 
|  427     auto it = channels_.find(component); |  | 
|  428     return (it != channels_.end()) ? it->second : nullptr; |  | 
|  429   } |  | 
|  430  |  | 
|  431   void SetChannelDestination(int component, FakeTransportChannel* channel) { |  | 
|  432     FakeTransportChannel* dest_channel = nullptr; |  | 
|  433     if (dest_) { |  | 
|  434       dest_channel = dest_->GetFakeChannel(component); |  | 
|  435       if (dest_channel) { |  | 
|  436         dest_channel->SetLocalCertificate(dest_->certificate_); |  | 
|  437       } |  | 
|  438     } |  | 
|  439     channel->SetDestination(dest_channel); |  | 
|  440   } |  | 
|  441  |  | 
|  442   // Note, this is distinct from the Channel map owned by Transport. |  | 
|  443   // This map just tracks the FakeTransportChannels created by this class. |  | 
|  444   // It's mainly needed so that we can access a FakeTransportChannel directly, |  | 
|  445   // even if wrapped by a DtlsTransportChannelWrapper. |  | 
|  446   ChannelMap channels_; |  | 
|  447   FakeTransport* dest_ = nullptr; |  | 
|  448   bool async_ = false; |  | 
|  449   rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |  | 
|  450   rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_10; |  | 
|  451 }; |  | 
|  452  |  | 
|  453 // Fake TransportController class, which can be passed into a BaseChannel object |  | 
|  454 // for test purposes. Can be connected to other FakeTransportControllers via |  | 
|  455 // Connect(). |  | 
|  456 // |  | 
|  457 // This fake is unusual in that for the most part, it's implemented with the |  | 
|  458 // real TransportController code, but with fake TransportChannels underneath. |  | 
|  459 class FakeTransportController : public TransportController { |  | 
|  460  public: |  | 
|  461   FakeTransportController() |  | 
|  462       : TransportController(rtc::Thread::Current(), |  | 
|  463                             rtc::Thread::Current(), |  | 
|  464                             nullptr), |  | 
|  465         fail_create_channel_(false) {} |  | 
|  466  |  | 
|  467   explicit FakeTransportController(IceRole role) |  | 
|  468       : TransportController(rtc::Thread::Current(), |  | 
|  469                             rtc::Thread::Current(), |  | 
|  470                             nullptr), |  | 
|  471         fail_create_channel_(false) { |  | 
|  472     SetIceRole(role); |  | 
|  473   } |  | 
|  474  |  | 
|  475   explicit FakeTransportController(rtc::Thread* worker_thread) |  | 
|  476       : TransportController(rtc::Thread::Current(), worker_thread, nullptr), |  | 
|  477         fail_create_channel_(false) {} |  | 
|  478  |  | 
|  479   FakeTransportController(rtc::Thread* worker_thread, IceRole role) |  | 
|  480       : TransportController(rtc::Thread::Current(), worker_thread, nullptr), |  | 
|  481         fail_create_channel_(false) { |  | 
|  482     SetIceRole(role); |  | 
|  483   } |  | 
|  484  |  | 
|  485   FakeTransport* GetTransport_w(const std::string& transport_name) { |  | 
|  486     return static_cast<FakeTransport*>( |  | 
|  487         TransportController::GetTransport_w(transport_name)); |  | 
|  488   } |  | 
|  489  |  | 
|  490   void Connect(FakeTransportController* dest) { |  | 
|  491     worker_thread()->Invoke<void>( |  | 
|  492         rtc::Bind(&FakeTransportController::Connect_w, this, dest)); |  | 
|  493   } |  | 
|  494  |  | 
|  495   TransportChannel* CreateTransportChannel_w(const std::string& transport_name, |  | 
|  496                                              int component) override { |  | 
|  497     if (fail_create_channel_) { |  | 
|  498       return nullptr; |  | 
|  499     } |  | 
|  500     return TransportController::CreateTransportChannel_w(transport_name, |  | 
|  501                                                          component); |  | 
|  502   } |  | 
|  503  |  | 
|  504   void set_fail_channel_creation(bool fail_channel_creation) { |  | 
|  505     fail_create_channel_ = fail_channel_creation; |  | 
|  506   } |  | 
|  507  |  | 
|  508  protected: |  | 
|  509   Transport* CreateTransport_w(const std::string& transport_name) override { |  | 
|  510     return new FakeTransport(transport_name); |  | 
|  511   } |  | 
|  512  |  | 
|  513   void Connect_w(FakeTransportController* dest) { |  | 
|  514     // Simulate the exchange of candidates. |  | 
|  515     ConnectChannels_w(); |  | 
|  516     dest->ConnectChannels_w(); |  | 
|  517     for (auto& kv : transports()) { |  | 
|  518       FakeTransport* transport = static_cast<FakeTransport*>(kv.second); |  | 
|  519       transport->SetDestination(dest->GetTransport_w(kv.first)); |  | 
|  520     } |  | 
|  521   } |  | 
|  522  |  | 
|  523   void ConnectChannels_w() { |  | 
|  524     for (auto& kv : transports()) { |  | 
|  525       FakeTransport* transport = static_cast<FakeTransport*>(kv.second); |  | 
|  526       transport->ConnectChannels(); |  | 
|  527       transport->MaybeStartGathering(); |  | 
|  528     } |  | 
|  529   } |  | 
|  530  |  | 
|  531  private: |  | 
|  532   bool fail_create_channel_; |  | 
|  533 }; |  | 
|  534  |  | 
|  535 }  // namespace cricket |  | 
|  536  |  | 
|  537 #endif  // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |  | 
| OLD | NEW |