| Index: webrtc/p2p/base/transport.cc
 | 
| diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc
 | 
| index 3e5f1b9f3a98ed1b953eb67a541d205a37965a4b..35a02e40e1b06693ebb88fcb686e663bddd75482 100644
 | 
| --- a/webrtc/p2p/base/transport.cc
 | 
| +++ b/webrtc/p2p/base/transport.cc
 | 
| @@ -72,44 +72,6 @@ Transport::~Transport() {
 | 
|    ASSERT(channels_destroyed_);
 | 
|  }
 | 
|  
 | 
| -bool Transport::AllChannelsCompleted() const {
 | 
| -  // We aren't completed until at least one channel is complete, so if there
 | 
| -  // are no channels, we aren't complete yet.
 | 
| -  if (channels_.empty()) {
 | 
| -    LOG(LS_INFO) << name() << " transport is not complete"
 | 
| -                 << " because it has no TransportChannels";
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  // A Transport's ICE process is completed if all of its channels are writable,
 | 
| -  // have finished allocating candidates, and have pruned all but one of their
 | 
| -  // connections.
 | 
| -  for (const auto& iter : channels_) {
 | 
| -    const TransportChannelImpl* channel = iter.second.get();
 | 
| -    bool complete =
 | 
| -        channel->writable() &&
 | 
| -        channel->GetState() == TransportChannelState::STATE_COMPLETED &&
 | 
| -        channel->GetIceRole() == ICEROLE_CONTROLLING &&
 | 
| -        channel->gathering_state() == kIceGatheringComplete;
 | 
| -    if (!complete) {
 | 
| -      LOG(LS_INFO) << name() << " transport is not complete"
 | 
| -                   << " because a channel is still incomplete.";
 | 
| -      return false;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -bool Transport::AnyChannelFailed() const {
 | 
| -  for (const auto& iter : channels_) {
 | 
| -    if (iter.second->GetState() == TransportChannelState::STATE_FAILED) {
 | 
| -      return true;
 | 
| -    }
 | 
| -  }
 | 
| -  return false;
 | 
| -}
 | 
| -
 | 
|  void Transport::SetIceRole(IceRole role) {
 | 
|    ice_role_ = role;
 | 
|    for (auto& iter : channels_) {
 | 
| @@ -239,23 +201,8 @@ TransportChannelImpl* Transport::CreateChannel(int component) {
 | 
|    if (local_description_ && remote_description_)
 | 
|      ApplyNegotiatedTransportDescription(impl, NULL);
 | 
|  
 | 
| -  impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState);
 | 
| -  impl->SignalReceivingState.connect(this, &Transport::OnChannelReceivingState);
 | 
| -  impl->SignalGatheringState.connect(this, &Transport::OnChannelGatheringState);
 | 
| -  impl->SignalCandidateGathered.connect(this,
 | 
| -                                        &Transport::OnChannelCandidateGathered);
 | 
| -  impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange);
 | 
| -  impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict);
 | 
| -  impl->SignalConnectionRemoved.connect(
 | 
| -      this, &Transport::OnChannelConnectionRemoved);
 | 
| -
 | 
|    if (connect_requested_) {
 | 
|      impl->Connect();
 | 
| -    if (channels_.size() == 1) {
 | 
| -      // If this is the first channel, then indicate that we have started
 | 
| -      // connecting.
 | 
| -      SignalConnecting(this);
 | 
| -    }
 | 
|    }
 | 
|    return impl;
 | 
|  }
 | 
| @@ -269,10 +216,10 @@ bool Transport::HasChannels() {
 | 
|    return !channels_.empty();
 | 
|  }
 | 
|  
 | 
| -void Transport::DestroyChannel(int component) {
 | 
| +bool Transport::DestroyChannel(int component) {
 | 
|    ChannelMap::iterator iter = channels_.find(component);
 | 
|    if (iter == channels_.end())
 | 
| -    return;
 | 
| +    return false;
 | 
|  
 | 
|    TransportChannelImpl* impl = NULL;
 | 
|  
 | 
| @@ -282,20 +229,11 @@ void Transport::DestroyChannel(int component) {
 | 
|      channels_.erase(iter);
 | 
|    }
 | 
|  
 | 
| -  if (connect_requested_ && channels_.empty()) {
 | 
| -    // We're no longer attempting to connect.
 | 
| -    SignalConnecting(this);
 | 
| -  }
 | 
| -
 | 
|    if (impl) {
 | 
|      DestroyTransportChannel(impl);
 | 
| -    // Need to update aggregate state after destroying a channel,
 | 
| -    // for example if it was the only one that wasn't yet writable.
 | 
| -    UpdateWritableState();
 | 
| -    UpdateReceivingState();
 | 
| -    UpdateGatheringState();
 | 
| -    MaybeSignalCompleted();
 | 
| +    return true;
 | 
|    }
 | 
| +  return false;
 | 
|  }
 | 
|  
 | 
|  void Transport::ConnectChannels() {
 | 
| @@ -321,9 +259,6 @@ void Transport::ConnectChannels() {
 | 
|    }
 | 
|  
 | 
|    CallChannels(&TransportChannelImpl::Connect);
 | 
| -  if (HasChannels()) {
 | 
| -    SignalConnecting(this);
 | 
| -  }
 | 
|  }
 | 
|  
 | 
|  void Transport::MaybeStartGathering() {
 | 
| @@ -429,159 +364,6 @@ bool Transport::AddRemoteCandidates(const std::vector<Candidate>& candidates,
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| -void Transport::OnChannelWritableState(TransportChannel* channel) {
 | 
| -  LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
 | 
| -               << " writability changed to " << channel->writable()
 | 
| -               << ". Check if transport is complete.";
 | 
| -  UpdateWritableState();
 | 
| -  MaybeSignalCompleted();
 | 
| -}
 | 
| -
 | 
| -void Transport::OnChannelReceivingState(TransportChannel* channel) {
 | 
| -  UpdateReceivingState();
 | 
| -}
 | 
| -
 | 
| -TransportState Transport::GetTransportState(TransportStateType state_type) {
 | 
| -  bool any = false;
 | 
| -  bool all = !channels_.empty();
 | 
| -  for (const auto iter : channels_) {
 | 
| -    bool b = false;
 | 
| -    switch (state_type) {
 | 
| -      case TRANSPORT_WRITABLE_STATE:
 | 
| -        b = iter.second->writable();
 | 
| -        break;
 | 
| -      case TRANSPORT_RECEIVING_STATE:
 | 
| -        b = iter.second->receiving();
 | 
| -        break;
 | 
| -      default:
 | 
| -        ASSERT(false);
 | 
| -    }
 | 
| -    any |= b;
 | 
| -    all &=  b;
 | 
| -  }
 | 
| -
 | 
| -  if (all) {
 | 
| -    return TRANSPORT_STATE_ALL;
 | 
| -  } else if (any) {
 | 
| -    return TRANSPORT_STATE_SOME;
 | 
| -  }
 | 
| -
 | 
| -  return TRANSPORT_STATE_NONE;
 | 
| -}
 | 
| -
 | 
| -void Transport::OnChannelGatheringState(TransportChannelImpl* channel) {
 | 
| -  ASSERT(channels_.find(channel->component()) != channels_.end());
 | 
| -  UpdateGatheringState();
 | 
| -  if (gathering_state_ == kIceGatheringComplete) {
 | 
| -    // If UpdateGatheringState brought us to kIceGatheringComplete, check if
 | 
| -    // our connection state is also "Completed". Otherwise, there's no point in
 | 
| -    // checking (since it would only produce log messages).
 | 
| -    MaybeSignalCompleted();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void Transport::OnChannelCandidateGathered(TransportChannelImpl* channel,
 | 
| -                                           const Candidate& candidate) {
 | 
| -  // We should never signal peer-reflexive candidates.
 | 
| -  if (candidate.type() == PRFLX_PORT_TYPE) {
 | 
| -    ASSERT(false);
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  ASSERT(connect_requested_);
 | 
| -  std::vector<Candidate> candidates;
 | 
| -  candidates.push_back(candidate);
 | 
| -  SignalCandidatesGathered(this, candidates);
 | 
| -}
 | 
| -
 | 
| -void Transport::OnChannelRouteChange(TransportChannel* channel,
 | 
| -                                     const Candidate& remote_candidate) {
 | 
| -  SignalRouteChange(this, remote_candidate.component(), remote_candidate);
 | 
| -}
 | 
| -
 | 
| -void Transport::OnRoleConflict(TransportChannelImpl* channel) {
 | 
| -  SignalRoleConflict();
 | 
| -}
 | 
| -
 | 
| -void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
 | 
| -  LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
 | 
| -               << " connection removed. Check if transport is complete.";
 | 
| -  MaybeSignalCompleted();
 | 
| -
 | 
| -  // Check if the state is now Failed.
 | 
| -  // Failed is only available in the Controlling ICE role.
 | 
| -  if (channel->GetIceRole() != ICEROLE_CONTROLLING) {
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  // Failed can only occur after candidate gathering has stopped.
 | 
| -  if (channel->gathering_state() != kIceGatheringComplete) {
 | 
| -    return;
 | 
| -  }
 | 
| -
 | 
| -  if (channel->GetState() == TransportChannelState::STATE_FAILED) {
 | 
| -    // A Transport has failed if any of its channels have no remaining
 | 
| -    // connections.
 | 
| -    SignalFailed(this);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void Transport::MaybeSignalCompleted() {
 | 
| -  if (AllChannelsCompleted()) {
 | 
| -    LOG(LS_INFO) << name() << " transport is complete"
 | 
| -                 << " because all the channels are complete.";
 | 
| -    SignalCompleted(this);
 | 
| -  }
 | 
| -  // TODO(deadbeef): Should we do anything if we previously were completed,
 | 
| -  // but now are not (if, for example, a new remote candidate is added)?
 | 
| -}
 | 
| -
 | 
| -void Transport::UpdateGatheringState() {
 | 
| -  IceGatheringState new_state = kIceGatheringNew;
 | 
| -  bool any_gathering = false;
 | 
| -  bool all_complete = !channels_.empty();
 | 
| -  for (const auto& kv : channels_) {
 | 
| -    any_gathering =
 | 
| -        any_gathering || kv.second->gathering_state() != kIceGatheringNew;
 | 
| -    all_complete =
 | 
| -        all_complete && kv.second->gathering_state() == kIceGatheringComplete;
 | 
| -  }
 | 
| -  if (all_complete) {
 | 
| -    new_state = kIceGatheringComplete;
 | 
| -  } else if (any_gathering) {
 | 
| -    new_state = kIceGatheringGathering;
 | 
| -  }
 | 
| -
 | 
| -  if (gathering_state_ != new_state) {
 | 
| -    gathering_state_ = new_state;
 | 
| -    if (gathering_state_ == kIceGatheringGathering) {
 | 
| -      LOG(LS_INFO) << "Transport: " << name_ << ", gathering candidates";
 | 
| -    } else if (gathering_state_ == kIceGatheringComplete) {
 | 
| -      LOG(LS_INFO) << "Transport " << name() << " gathering complete.";
 | 
| -    }
 | 
| -    SignalGatheringState(this);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void Transport::UpdateReceivingState() {
 | 
| -  TransportState receiving = GetTransportState(TRANSPORT_RECEIVING_STATE);
 | 
| -  if (receiving_ != receiving) {
 | 
| -    receiving_ = receiving;
 | 
| -    SignalReceivingState(this);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void Transport::UpdateWritableState() {
 | 
| -  TransportState writable = GetTransportState(TRANSPORT_WRITABLE_STATE);
 | 
| -  LOG(LS_INFO) << name() << " transport writable state changed? " << writable_
 | 
| -               << " => " << writable;
 | 
| -  if (writable_ != writable) {
 | 
| -    was_writable_ = (writable_ == TRANSPORT_STATE_ALL);
 | 
| -    writable_ = writable;
 | 
| -    SignalWritableState(this);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
|  bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch,
 | 
|                                                 std::string* error_desc) {
 | 
|    ch->SetIceCredentials(local_description_->ice_ufrag,
 | 
| 
 |