// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/media/rtc_peer_connection_handler.h"

#include <stddef.h>

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "content/child/child_process.h"
#include "content/renderer/media/media_stream.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "content/renderer/media/media_stream_audio_track.h"
#include "content/renderer/media/media_stream_source.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/mock_audio_device_factory.h"
#include "content/renderer/media/mock_constraint_factory.h"
#include "content/renderer/media/mock_data_channel_impl.h"
#include "content/renderer/media/mock_media_stream_video_source.h"
#include "content/renderer/media/mock_peer_connection_impl.h"
#include "content/renderer/media/mock_web_rtc_peer_connection_handler_client.h"
#include "content/renderer/media/peer_connection_tracker.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/processed_local_audio_source.h"
#include "content/renderer/media/webrtc/rtc_stats.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"
#include "third_party/WebKit/public/platform/WebMediaStream.h"
#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
#include "third_party/WebKit/public/platform/WebRTCConfiguration.h"
#include "third_party/WebKit/public/platform/WebRTCDTMFSenderHandler.h"
#include "third_party/WebKit/public/platform/WebRTCDataChannelHandler.h"
#include "third_party/WebKit/public/platform/WebRTCDataChannelInit.h"
#include "third_party/WebKit/public/platform/WebRTCError.h"
#include "third_party/WebKit/public/platform/WebRTCICECandidate.h"
#include "third_party/WebKit/public/platform/WebRTCPeerConnectionHandlerClient.h"
#include "third_party/WebKit/public/platform/WebRTCSessionDescription.h"
#include "third_party/WebKit/public/platform/WebRTCSessionDescriptionRequest.h"
#include "third_party/WebKit/public/platform/WebRTCStatsRequest.h"
#include "third_party/WebKit/public/platform/WebRTCVoidRequest.h"
#include "third_party/WebKit/public/platform/WebURL.h"
#include "third_party/WebKit/public/web/WebHeap.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/stats/test/rtcteststats.h"

static const char kDummySdp[] = "dummy sdp";
static const char kDummySdpType[] = "dummy type";

using blink::WebRTCPeerConnectionHandlerClient;
using testing::NiceMock;
using testing::_;
using testing::Ref;
using testing::SaveArg;

namespace content {

ACTION_P2(ExitMessageLoop, message_loop, quit_closure) {
  message_loop->task_runner()->PostTask(FROM_HERE, quit_closure);
}

class MockRTCStatsResponse : public LocalRTCStatsResponse {
 public:
  MockRTCStatsResponse()
      : report_count_(0),
        statistic_count_(0) {
  }

  void addStats(const blink::WebRTCLegacyStats& stats) override {
    ++report_count_;
    for (std::unique_ptr<blink::WebRTCLegacyStatsMemberIterator> member(
             stats.iterator());
         !member->isEnd(); member->next()) {
      ++statistic_count_;
    }
  }

  int report_count() const { return report_count_; }

 private:
  int report_count_;
  int statistic_count_;
};

// Mocked wrapper for blink::WebRTCStatsRequest
class MockRTCStatsRequest : public LocalRTCStatsRequest {
 public:
  MockRTCStatsRequest()
      : has_selector_(false),
        request_succeeded_called_(false) {}

  bool hasSelector() const override { return has_selector_; }
  blink::WebMediaStreamTrack component() const override { return component_; }
  scoped_refptr<LocalRTCStatsResponse> createResponse() override {
    DCHECK(!response_.get());
    response_ = new rtc::RefCountedObject<MockRTCStatsResponse>();
    return response_;
  }

  void requestSucceeded(const LocalRTCStatsResponse* response) override {
    EXPECT_EQ(response, response_.get());
    request_succeeded_called_ = true;
  }

  // Function for setting whether or not a selector is available.
  void setSelector(const blink::WebMediaStreamTrack& component) {
    has_selector_ = true;
    component_ = component;
  }

  // Function for inspecting the result of a stats request.
  MockRTCStatsResponse* result() {
    if (request_succeeded_called_) {
      return response_.get();
    } else {
      return NULL;
    }
  }

 private:
  bool has_selector_;
  blink::WebMediaStreamTrack component_;
  scoped_refptr<MockRTCStatsResponse> response_;
  bool request_succeeded_called_;
};

class MockPeerConnectionTracker : public PeerConnectionTracker {
 public:
  MOCK_METHOD1(UnregisterPeerConnection,
               void(RTCPeerConnectionHandler* pc_handler));
  // TODO(jiayl): add coverage for the following methods
  MOCK_METHOD2(TrackCreateOffer,
               void(RTCPeerConnectionHandler* pc_handler,
                    const blink::WebMediaConstraints& constraints));
  MOCK_METHOD2(TrackCreateAnswer,
               void(RTCPeerConnectionHandler* pc_handler,
                    const blink::WebMediaConstraints& constraints));
  MOCK_METHOD4(TrackSetSessionDescription,
               void(RTCPeerConnectionHandler* pc_handler,
                    const std::string& sdp, const std::string& type,
                    Source source));
  MOCK_METHOD2(
      TrackSetConfiguration,
      void(RTCPeerConnectionHandler* pc_handler,
           const webrtc::PeerConnectionInterface::RTCConfiguration& config));
  MOCK_METHOD4(TrackAddIceCandidate,
               void(RTCPeerConnectionHandler* pc_handler,
                    const blink::WebRTCICECandidate& candidate,
                    Source source,
                    bool succeeded));
  MOCK_METHOD3(TrackAddStream,
               void(RTCPeerConnectionHandler* pc_handler,
                    const blink::WebMediaStream& stream,
                    Source source));
  MOCK_METHOD3(TrackRemoveStream,
               void(RTCPeerConnectionHandler* pc_handler,
                    const blink::WebMediaStream& stream,
                    Source source));
  MOCK_METHOD1(TrackOnIceComplete,
               void(RTCPeerConnectionHandler* pc_handler));
  MOCK_METHOD3(TrackCreateDataChannel,
               void(RTCPeerConnectionHandler* pc_handler,
                    const webrtc::DataChannelInterface* data_channel,
                    Source source));
  MOCK_METHOD1(TrackStop, void(RTCPeerConnectionHandler* pc_handler));
  MOCK_METHOD2(TrackSignalingStateChange,
               void(RTCPeerConnectionHandler* pc_handler,
                    WebRTCPeerConnectionHandlerClient::SignalingState state));
  MOCK_METHOD2(
      TrackIceConnectionStateChange,
      void(RTCPeerConnectionHandler* pc_handler,
           WebRTCPeerConnectionHandlerClient::ICEConnectionState state));
  MOCK_METHOD2(
      TrackIceGatheringStateChange,
      void(RTCPeerConnectionHandler* pc_handler,
           WebRTCPeerConnectionHandlerClient::ICEGatheringState state));
  MOCK_METHOD4(TrackSessionDescriptionCallback,
               void(RTCPeerConnectionHandler* pc_handler,
                    Action action,
                    const std::string& type,
                    const std::string& value));
  MOCK_METHOD1(TrackOnRenegotiationNeeded,
               void(RTCPeerConnectionHandler* pc_handler));
  MOCK_METHOD2(TrackCreateDTMFSender,
               void(RTCPeerConnectionHandler* pc_handler,
                     const blink::WebMediaStreamTrack& track));
};

class MockRTCStatsReportCallback : public blink::WebRTCStatsReportCallback {
 public:
  explicit MockRTCStatsReportCallback(
      std::unique_ptr<blink::WebRTCStatsReport>* result)
      : main_thread_(base::ThreadTaskRunnerHandle::Get()), result_(result) {
    DCHECK(result_);
  }

  void OnStatsDelivered(
      std::unique_ptr<blink::WebRTCStatsReport> report) override {
    EXPECT_TRUE(main_thread_->BelongsToCurrentThread());
    EXPECT_TRUE(report);
    result_->reset(report.release());
  }

 private:
  scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
  std::unique_ptr<blink::WebRTCStatsReport>* result_;
};

template<typename T>
std::vector<T> ToSequence(T value) {
  std::vector<T> vec;
  vec.push_back(value);
  return vec;
}

template<typename T>
void ExpectSequenceEquals(const blink::WebVector<T>& sequence, T value) {
  EXPECT_EQ(sequence.size(), static_cast<size_t>(1));
  EXPECT_EQ(sequence[0], value);
}

class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
 public:
  RTCPeerConnectionHandlerUnderTest(
      WebRTCPeerConnectionHandlerClient* client,
      PeerConnectionDependencyFactory* dependency_factory)
      : RTCPeerConnectionHandler(client, dependency_factory) {
  }

  MockPeerConnectionImpl* native_peer_connection() {
    return static_cast<MockPeerConnectionImpl*>(
        RTCPeerConnectionHandler::native_peer_connection());
  }

  webrtc::PeerConnectionObserver* observer() {
    return native_peer_connection()->observer();
  }

  scoped_refptr<base::SingleThreadTaskRunner>
  signaling_thread() const override {
    return base::ThreadTaskRunnerHandle::Get();
  }
};

class RTCPeerConnectionHandlerTest : public ::testing::Test {
 public:
  RTCPeerConnectionHandlerTest() : mock_peer_connection_(NULL) {
    child_process_.reset(new ChildProcess());
  }

  void SetUp() override {
    mock_client_.reset(new NiceMock<MockWebRTCPeerConnectionHandlerClient>());
    mock_dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
    pc_handler_.reset(
        new RTCPeerConnectionHandlerUnderTest(
            mock_client_.get(), mock_dependency_factory_.get()));
    mock_tracker_.reset(new NiceMock<MockPeerConnectionTracker>());
    blink::WebRTCConfiguration config;
    blink::WebMediaConstraints constraints;
    EXPECT_TRUE(pc_handler_->InitializeForTest(
        config, constraints, mock_tracker_.get()->AsWeakPtr()));

    mock_peer_connection_ = pc_handler_->native_peer_connection();
    ASSERT_TRUE(mock_peer_connection_);
    EXPECT_CALL(*mock_peer_connection_, Close());
  }

  void TearDown() override {
    pc_handler_.reset();
    mock_tracker_.reset();
    mock_dependency_factory_.reset();
    mock_client_.reset();
    blink::WebHeap::collectAllGarbageForTesting();
  }

  // Creates a WebKit local MediaStream.
  blink::WebMediaStream CreateLocalMediaStream(
      const std::string& stream_label) {
    std::string video_track_label("video-label");
    std::string audio_track_label("audio-label");
    blink::WebMediaStreamSource blink_audio_source;
    blink_audio_source.initialize(blink::WebString::fromUTF8(audio_track_label),
                                  blink::WebMediaStreamSource::TypeAudio,
                                  blink::WebString::fromUTF8("audio_track"));
    ProcessedLocalAudioSource* const audio_source =
        new ProcessedLocalAudioSource(
            -1 /* consumer_render_frame_id is N/A for non-browser tests */,
            StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE, "Mock device",
                             "mock_device_id",
                             media::AudioParameters::kAudioCDSampleRate,
                             media::CHANNEL_LAYOUT_STEREO,
                             media::AudioParameters::kAudioCDSampleRate / 100),
            MockConstraintFactory().CreateWebMediaConstraints(),
            base::Bind(&RTCPeerConnectionHandlerTest::OnAudioSourceStarted),
            mock_dependency_factory_.get());
    audio_source->SetAllowInvalidRenderFrameIdForTesting(true);
    blink_audio_source.setExtraData(audio_source);  // Takes ownership.

    blink::WebMediaStreamSource video_source;
    video_source.initialize(blink::WebString::fromUTF8(video_track_label),
                            blink::WebMediaStreamSource::TypeVideo,
                            blink::WebString::fromUTF8("video_track"));
    MockMediaStreamVideoSource* native_video_source =
        new MockMediaStreamVideoSource(false);
    video_source.setExtraData(native_video_source);

    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks(
        static_cast<size_t>(1));
    audio_tracks[0].initialize(blink_audio_source.id(), blink_audio_source);
    EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(),
                Initialize(_, _, -1));
    EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(),
                SetAutomaticGainControl(true));
    EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(), Start());
    EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(), Stop());
    CHECK(audio_source->ConnectToTrack(audio_tracks[0]));
    blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
        static_cast<size_t>(1));
    blink::WebMediaConstraints video_constraints;
    video_constraints.initialize();
    video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
        native_video_source, video_constraints,
        MediaStreamVideoSource::ConstraintsCallback(), true);

    blink::WebMediaStream local_stream;
    local_stream.initialize(blink::WebString::fromUTF8(stream_label),
                            audio_tracks, video_tracks);
    local_stream.setExtraData(new MediaStream());
    return local_stream;
  }

  // Creates a remote MediaStream and adds it to the mocked native
  // peer connection.
  rtc::scoped_refptr<webrtc::MediaStreamInterface> AddRemoteMockMediaStream(
      const std::string& stream_label,
      const std::string& video_track_label,
      const std::string& audio_track_label) {
    rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
        mock_dependency_factory_->CreateLocalMediaStream(stream_label).get());
    if (!video_track_label.empty()) {
      stream->AddTrack(MockWebRtcVideoTrack::Create(video_track_label).get());
    }
    if (!audio_track_label.empty()) {
      stream->AddTrack(MockWebRtcAudioTrack::Create(audio_track_label).get());
    }
    mock_peer_connection_->AddRemoteStream(stream);
    return stream;
  }

  void StopAllTracks(const blink::WebMediaStream& stream) {
    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
    stream.audioTracks(audio_tracks);
    for (const auto& track : audio_tracks)
      MediaStreamAudioTrack::From(track)->Stop();

    blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
    stream.videoTracks(video_tracks);
    for (const auto& track : video_tracks)
      MediaStreamVideoTrack::GetVideoTrack(track)->Stop();
  }

  static void OnAudioSourceStarted(MediaStreamSource* source,
                                   MediaStreamRequestResult result,
                                   const blink::WebString& result_name) {}

  base::MessageLoop message_loop_;
  std::unique_ptr<ChildProcess> child_process_;
  std::unique_ptr<MockWebRTCPeerConnectionHandlerClient> mock_client_;
  std::unique_ptr<MockPeerConnectionDependencyFactory> mock_dependency_factory_;
  std::unique_ptr<NiceMock<MockPeerConnectionTracker>> mock_tracker_;
  std::unique_ptr<RTCPeerConnectionHandlerUnderTest> pc_handler_;
  MockAudioDeviceFactory mock_audio_device_factory_;

  // Weak reference to the mocked native peer connection implementation.
  MockPeerConnectionImpl* mock_peer_connection_;
};

TEST_F(RTCPeerConnectionHandlerTest, Destruct) {
  EXPECT_CALL(*mock_tracker_.get(), UnregisterPeerConnection(pc_handler_.get()))
      .Times(1);
  pc_handler_.reset(NULL);
}

TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
  pc_handler_->stop();

  EXPECT_CALL(*mock_client_.get(), negotiationNeeded()).Times(0);
  pc_handler_->observer()->OnRenegotiationNeeded();

  EXPECT_CALL(*mock_client_.get(), didGenerateICECandidate(_)).Times(0);
  std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
      mock_dependency_factory_->CreateIceCandidate("sdpMid", 1, kDummySdp));
  pc_handler_->observer()->OnIceCandidate(native_candidate.get());

  EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(_)).Times(0);
  pc_handler_->observer()->OnSignalingChange(
      webrtc::PeerConnectionInterface::kHaveRemoteOffer);

  EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(_)).Times(0);
  pc_handler_->observer()->OnIceGatheringChange(
      webrtc::PeerConnectionInterface::kIceGatheringNew);

  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(_)).Times(0);
  pc_handler_->observer()->OnIceConnectionChange(
      webrtc::PeerConnectionInterface::kIceConnectionDisconnected);

  EXPECT_CALL(*mock_client_.get(), didAddRemoteStream(_)).Times(0);
  std::string remote_stream_label("remote_stream");
  rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
      AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
  pc_handler_->observer()->OnAddStream(remote_stream);

  EXPECT_CALL(*mock_client_.get(), didRemoveRemoteStream(_)).Times(0);
  pc_handler_->observer()->OnRemoveStream(remote_stream);

  EXPECT_CALL(*mock_client_.get(), didAddRemoteDataChannel(_)).Times(0);
  webrtc::DataChannelInit config;
  rtc::scoped_refptr<webrtc::DataChannelInterface> remote_data_channel(
      new rtc::RefCountedObject<MockDataChannel>("dummy", &config));
  pc_handler_->observer()->OnDataChannel(remote_data_channel);

  base::RunLoop().RunUntilIdle();
}

TEST_F(RTCPeerConnectionHandlerTest, DestructAllHandlers) {
  EXPECT_CALL(*mock_client_.get(), releasePeerConnectionHandler())
      .Times(1);
  RTCPeerConnectionHandler::DestructAllHandlers();
}

TEST_F(RTCPeerConnectionHandlerTest, CreateOffer) {
  blink::WebRTCSessionDescriptionRequest request;
  blink::WebMediaConstraints options;
  EXPECT_CALL(*mock_tracker_.get(), TrackCreateOffer(pc_handler_.get(), _));

  // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
  // the |reqest| requestSucceeded can be tested? Currently the |request| object
  // can not be initialized from a unit test.
  EXPECT_FALSE(mock_peer_connection_->created_session_description() != NULL);
  pc_handler_->createOffer(request, options);
  EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
}

TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) {
  blink::WebRTCSessionDescriptionRequest request;
  blink::WebMediaConstraints options;
  EXPECT_CALL(*mock_tracker_.get(), TrackCreateAnswer(pc_handler_.get(), _));
  // TODO(perkj): Can blink::WebRTCSessionDescriptionRequest be changed so
  // the |reqest| requestSucceeded can be tested? Currently the |request| object
  // can not be initialized from a unit test.
  EXPECT_FALSE(mock_peer_connection_->created_session_description() != NULL);
  pc_handler_->createAnswer(request, options);
  EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
}

TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) {
  blink::WebRTCVoidRequest request;
  blink::WebRTCSessionDescription description;
  description.initialize(kDummySdpType, kDummySdp);
  // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
  // before |mock_peer_connection| is called.
  testing::InSequence sequence;
  EXPECT_CALL(*mock_tracker_.get(),
              TrackSetSessionDescription(pc_handler_.get(), kDummySdp,
                                         kDummySdpType,
                                         PeerConnectionTracker::SOURCE_LOCAL));
  EXPECT_CALL(*mock_peer_connection_, SetLocalDescription(_, _));

  pc_handler_->setLocalDescription(request, description);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(description.type(), pc_handler_->localDescription().type());
  EXPECT_EQ(description.sdp(), pc_handler_->localDescription().sdp());

  std::string sdp_string;
  ASSERT_TRUE(mock_peer_connection_->local_description() != NULL);
  EXPECT_EQ(kDummySdpType, mock_peer_connection_->local_description()->type());
  mock_peer_connection_->local_description()->ToString(&sdp_string);
  EXPECT_EQ(kDummySdp, sdp_string);

  // TODO(deadbeef): Also mock the "success" callback from the PeerConnection
  // and ensure that the sucessful result is tracked by PeerConnectionTracker.
}

// Test that setLocalDescription with invalid SDP will result in a failure, and
// is tracked as a failure with PeerConnectionTracker.
TEST_F(RTCPeerConnectionHandlerTest, setLocalDescriptionParseError) {
  blink::WebRTCVoidRequest request;
  blink::WebRTCSessionDescription description;
  description.initialize(kDummySdpType, kDummySdp);
  testing::InSequence sequence;
  // Expect two "Track" calls, one for the start of the attempt and one for the
  // failure.
  EXPECT_CALL(
      *mock_tracker_.get(),
      TrackSetSessionDescription(pc_handler_.get(), kDummySdp, kDummySdpType,
                                 PeerConnectionTracker::SOURCE_LOCAL));
  EXPECT_CALL(
      *mock_tracker_.get(),
      TrackSessionDescriptionCallback(
          pc_handler_.get(),
          PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION, "OnFailure", _));

  // Used to simulate a parse failure.
  mock_dependency_factory_->SetFailToCreateSessionDescription(true);
  pc_handler_->setLocalDescription(request, description);
  base::RunLoop().RunUntilIdle();
  // A description that failed to be applied shouldn't be stored.
  EXPECT_TRUE(pc_handler_->localDescription().sdp().isEmpty());
}

TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) {
  blink::WebRTCVoidRequest request;
  blink::WebRTCSessionDescription description;
  description.initialize(kDummySdpType, kDummySdp);

  // PeerConnectionTracker::TrackSetSessionDescription is expected to be called
  // before |mock_peer_connection| is called.
  testing::InSequence sequence;
  EXPECT_CALL(*mock_tracker_.get(),
              TrackSetSessionDescription(pc_handler_.get(), kDummySdp,
                                         kDummySdpType,
                                         PeerConnectionTracker::SOURCE_REMOTE));
  EXPECT_CALL(*mock_peer_connection_, SetRemoteDescription(_, _));

  pc_handler_->setRemoteDescription(request, description);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(description.type(), pc_handler_->remoteDescription().type());
  EXPECT_EQ(description.sdp(), pc_handler_->remoteDescription().sdp());

  std::string sdp_string;
  ASSERT_TRUE(mock_peer_connection_->remote_description() != NULL);
  EXPECT_EQ(kDummySdpType, mock_peer_connection_->remote_description()->type());
  mock_peer_connection_->remote_description()->ToString(&sdp_string);
  EXPECT_EQ(kDummySdp, sdp_string);

  // TODO(deadbeef): Also mock the "success" callback from the PeerConnection
  // and ensure that the sucessful result is tracked by PeerConnectionTracker.
}

// Test that setRemoteDescription with invalid SDP will result in a failure, and
// is tracked as a failure with PeerConnectionTracker.
TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescriptionParseError) {
  blink::WebRTCVoidRequest request;
  blink::WebRTCSessionDescription description;
  description.initialize(kDummySdpType, kDummySdp);
  testing::InSequence sequence;
  // Expect two "Track" calls, one for the start of the attempt and one for the
  // failure.
  EXPECT_CALL(
      *mock_tracker_.get(),
      TrackSetSessionDescription(pc_handler_.get(), kDummySdp, kDummySdpType,
                                 PeerConnectionTracker::SOURCE_REMOTE));
  EXPECT_CALL(*mock_tracker_.get(),
              TrackSessionDescriptionCallback(
                  pc_handler_.get(),
                  PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION,
                  "OnFailure", _));

  // Used to simulate a parse failure.
  mock_dependency_factory_->SetFailToCreateSessionDescription(true);
  pc_handler_->setRemoteDescription(request, description);
  base::RunLoop().RunUntilIdle();
  // A description that failed to be applied shouldn't be stored.
  EXPECT_TRUE(pc_handler_->remoteDescription().sdp().isEmpty());
}

TEST_F(RTCPeerConnectionHandlerTest, setConfiguration) {
  blink::WebRTCConfiguration config;

  EXPECT_CALL(*mock_tracker_.get(),
              TrackSetConfiguration(pc_handler_.get(), _));
  // TODO(perkj): Test that the parameters in |config| can be translated when a
  // WebRTCConfiguration can be constructed. It's WebKit class and can't be
  // initialized from a test.
  EXPECT_EQ(blink::WebRTCErrorType::kNone,
            pc_handler_->setConfiguration(config));
}

// Test that when an error occurs in SetConfiguration, it's converted to a
// blink error and false is returned.
TEST_F(RTCPeerConnectionHandlerTest, setConfigurationError) {
  blink::WebRTCConfiguration config;

  mock_peer_connection_->set_setconfiguration_error_type(
      webrtc::RTCErrorType::INVALID_MODIFICATION);
  EXPECT_CALL(*mock_tracker_.get(),
              TrackSetConfiguration(pc_handler_.get(), _));
  EXPECT_EQ(blink::WebRTCErrorType::kInvalidModification,
            pc_handler_->setConfiguration(config));
}

TEST_F(RTCPeerConnectionHandlerTest, addICECandidate) {
  blink::WebRTCICECandidate candidate;
  candidate.initialize(kDummySdp, "sdpMid", 1);

  EXPECT_CALL(*mock_tracker_.get(),
              TrackAddIceCandidate(pc_handler_.get(),
                                   testing::Ref(candidate),
                                   PeerConnectionTracker::SOURCE_REMOTE,
                                   true));
  EXPECT_TRUE(pc_handler_->addICECandidate(candidate));
  EXPECT_EQ(kDummySdp, mock_peer_connection_->ice_sdp());
  EXPECT_EQ(1, mock_peer_connection_->sdp_mline_index());
  EXPECT_EQ("sdpMid", mock_peer_connection_->sdp_mid());
}

TEST_F(RTCPeerConnectionHandlerTest, addAndRemoveStream) {
  std::string stream_label = "local_stream";
  blink::WebMediaStream local_stream(
      CreateLocalMediaStream(stream_label));
  blink::WebMediaConstraints constraints;

  EXPECT_CALL(*mock_tracker_.get(),
              TrackAddStream(pc_handler_.get(),
                             testing::Ref(local_stream),
                             PeerConnectionTracker::SOURCE_LOCAL));
  EXPECT_CALL(*mock_tracker_.get(),
              TrackRemoveStream(pc_handler_.get(),
                                testing::Ref(local_stream),
                                PeerConnectionTracker::SOURCE_LOCAL));
  EXPECT_TRUE(pc_handler_->addStream(local_stream, constraints));
  EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
  EXPECT_EQ(1u,
      mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
  EXPECT_EQ(1u,
      mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());

  EXPECT_FALSE(pc_handler_->addStream(local_stream, constraints));

  pc_handler_->removeStream(local_stream);
  EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count());

  StopAllTracks(local_stream);
}

TEST_F(RTCPeerConnectionHandlerTest, addStreamWithStoppedAudioAndVideoTrack) {
  std::string stream_label = "local_stream";
  blink::WebMediaStream local_stream(
      CreateLocalMediaStream(stream_label));
  blink::WebMediaConstraints constraints;

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
  local_stream.audioTracks(audio_tracks);
  MediaStreamAudioSource* native_audio_source =
      MediaStreamAudioSource::From(audio_tracks[0].source());
  native_audio_source->StopSource();

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  local_stream.videoTracks(video_tracks);
  MediaStreamVideoSource* native_video_source =
      static_cast<MediaStreamVideoSource*>(
          video_tracks[0].source().getExtraData());
  native_video_source->StopSource();

  EXPECT_TRUE(pc_handler_->addStream(local_stream, constraints));
  EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
  EXPECT_EQ(
      1u,
      mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
  EXPECT_EQ(
      1u,
      mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());

  StopAllTracks(local_stream);
}

TEST_F(RTCPeerConnectionHandlerTest, GetStatsNoSelector) {
  scoped_refptr<MockRTCStatsRequest> request(
      new rtc::RefCountedObject<MockRTCStatsRequest>());
  pc_handler_->getStats(request.get());
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(request->result());
  EXPECT_LT(1, request->result()->report_count());
}

TEST_F(RTCPeerConnectionHandlerTest, GetStatsAfterClose) {
  scoped_refptr<MockRTCStatsRequest> request(
      new rtc::RefCountedObject<MockRTCStatsRequest>());
  pc_handler_->stop();
  base::RunLoop().RunUntilIdle();
  pc_handler_->getStats(request.get());
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(request->result());
  EXPECT_LT(1, request->result()->report_count());
}

TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
  blink::WebMediaStream local_stream(
      CreateLocalMediaStream("local_stream"));
  blink::WebMediaConstraints constraints;
  pc_handler_->addStream(local_stream, constraints);
  blink::WebVector<blink::WebMediaStreamTrack> tracks;
  local_stream.audioTracks(tracks);
  ASSERT_LE(1ul, tracks.size());

  scoped_refptr<MockRTCStatsRequest> request(
      new rtc::RefCountedObject<MockRTCStatsRequest>());
  request->setSelector(tracks[0]);
  pc_handler_->getStats(request.get());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, request->result()->report_count());

  StopAllTracks(local_stream);
}

TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithRemoteSelector) {
  rtc::scoped_refptr<webrtc::MediaStreamInterface> stream(
      AddRemoteMockMediaStream("remote_stream", "video", "audio"));
  pc_handler_->observer()->OnAddStream(stream);
  base::RunLoop().RunUntilIdle();
  const blink::WebMediaStream& remote_stream = mock_client_->remote_stream();

  blink::WebVector<blink::WebMediaStreamTrack> tracks;
  remote_stream.audioTracks(tracks);
  ASSERT_LE(1ul, tracks.size());

  scoped_refptr<MockRTCStatsRequest> request(
      new rtc::RefCountedObject<MockRTCStatsRequest>());
  request->setSelector(tracks[0]);
  pc_handler_->getStats(request.get());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, request->result()->report_count());
}

TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) {
  // The setup is the same as GetStatsWithLocalSelector, but the stream is not
  // added to the PeerConnection.
  blink::WebMediaStream local_stream(
      CreateLocalMediaStream("local_stream_2"));
  blink::WebMediaConstraints constraints;
  blink::WebVector<blink::WebMediaStreamTrack> tracks;

  local_stream.audioTracks(tracks);
  blink::WebMediaStreamTrack component = tracks[0];
  mock_peer_connection_->SetGetStatsResult(false);

  scoped_refptr<MockRTCStatsRequest> request(
      new rtc::RefCountedObject<MockRTCStatsRequest>());
  request->setSelector(component);
  pc_handler_->getStats(request.get());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, request->result()->report_count());

  StopAllTracks(local_stream);
}

TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) {
  WhitelistStatsForTesting(webrtc::RTCTestStats::kType);

  rtc::scoped_refptr<webrtc::RTCStatsReport> report =
      webrtc::RTCStatsReport::Create();

  report->AddStats(std::unique_ptr<const webrtc::RTCStats>(
      new webrtc::RTCTestStats("RTCUndefinedStats", 1000)));

  std::unique_ptr<webrtc::RTCTestStats> stats_defined_members(
      new webrtc::RTCTestStats("RTCDefinedStats", 2000));
  stats_defined_members->m_bool = true;
  stats_defined_members->m_int32 = 42;
  stats_defined_members->m_uint32 = 42;
  stats_defined_members->m_int64 = 42;
  stats_defined_members->m_uint64 = 42;
  stats_defined_members->m_double = 42.0;
  stats_defined_members->m_string = "42";
  stats_defined_members->m_sequence_bool = ToSequence<bool>(true);
  stats_defined_members->m_sequence_int32 = ToSequence<int32_t>(42);
  stats_defined_members->m_sequence_uint32 = ToSequence<uint32_t>(42);
  stats_defined_members->m_sequence_int64 = ToSequence<int64_t>(42);
  stats_defined_members->m_sequence_uint64 = ToSequence<uint64_t>(42);
  stats_defined_members->m_sequence_double = ToSequence<double>(42);
  stats_defined_members->m_sequence_string = ToSequence<std::string>("42");
  report->AddStats(std::unique_ptr<const webrtc::RTCStats>(
      stats_defined_members.release()));

  pc_handler_->native_peer_connection()->SetGetStatsReport(report);
  std::unique_ptr<blink::WebRTCStatsReport> result;
  pc_handler_->getStats(std::unique_ptr<blink::WebRTCStatsReportCallback>(
      new MockRTCStatsReportCallback(&result)));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(result);

  int undefined_stats_count = 0;
  int defined_stats_count = 0;
  for (std::unique_ptr<blink::WebRTCStats> stats = result->next(); stats;
       stats.reset(result->next().release())) {
    EXPECT_EQ(stats->type().utf8(), webrtc::RTCTestStats::kType);
    if (stats->id().utf8() == "RTCUndefinedStats") {
      ++undefined_stats_count;
      EXPECT_EQ(stats->timestamp(), 1.0);
      for (size_t i = 0; i < stats->membersCount(); ++i) {
        EXPECT_FALSE(stats->getMember(i)->isDefined());
      }
    } else if (stats->id().utf8() == "RTCDefinedStats") {
      ++defined_stats_count;
      EXPECT_EQ(stats->timestamp(), 2.0);
      std::set<blink::WebRTCStatsMemberType> members;
      for (size_t i = 0; i < stats->membersCount(); ++i) {
        std::unique_ptr<blink::WebRTCStatsMember> member =
            stats->getMember(i);
        // TODO(hbos): A WebRTC-change is adding new members, this would cause
        // not all members to be defined. This if-statement saves Chromium from
        // crashing. As soon as the change has been rolled in, I will update
        // this test. crbug.com/627816
        if (!member->isDefined())
          continue;
        EXPECT_TRUE(member->isDefined());
        members.insert(member->type());
        switch (member->type()) {
          case blink::WebRTCStatsMemberTypeBool:
            EXPECT_EQ(member->valueBool(), true);
            break;
          case blink::WebRTCStatsMemberTypeInt32:
            EXPECT_EQ(member->valueInt32(), static_cast<int32_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeUint32:
            EXPECT_EQ(member->valueUint32(), static_cast<uint32_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeInt64:
            EXPECT_EQ(member->valueInt64(), static_cast<int64_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeUint64:
            EXPECT_EQ(member->valueUint64(), static_cast<uint64_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeDouble:
            EXPECT_EQ(member->valueDouble(), 42.0);
            break;
          case blink::WebRTCStatsMemberTypeString:
            EXPECT_EQ(member->valueString(), blink::WebString::fromUTF8("42"));
            break;
          case blink::WebRTCStatsMemberTypeSequenceBool:
            ExpectSequenceEquals(member->valueSequenceBool(), 1);
            break;
          case blink::WebRTCStatsMemberTypeSequenceInt32:
            ExpectSequenceEquals(member->valueSequenceInt32(),
                                 static_cast<int32_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeSequenceUint32:
            ExpectSequenceEquals(member->valueSequenceUint32(),
                                 static_cast<uint32_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeSequenceInt64:
            ExpectSequenceEquals(member->valueSequenceInt64(),
                                 static_cast<int64_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeSequenceUint64:
            ExpectSequenceEquals(member->valueSequenceUint64(),
                                 static_cast<uint64_t>(42));
            break;
          case blink::WebRTCStatsMemberTypeSequenceDouble:
            ExpectSequenceEquals(member->valueSequenceDouble(), 42.0);
            break;
          case blink::WebRTCStatsMemberTypeSequenceString:
            ExpectSequenceEquals(member->valueSequenceString(),
                                 blink::WebString::fromUTF8("42"));
            break;
          default:
            NOTREACHED();
        }
      }
      EXPECT_EQ(members.size(), static_cast<size_t>(14));
    } else {
      NOTREACHED();
    }
  }
  EXPECT_EQ(undefined_stats_count, 1);
  EXPECT_EQ(defined_stats_count, 1);
}

TEST_F(RTCPeerConnectionHandlerTest, OnSignalingChange) {
  testing::InSequence sequence;

  webrtc::PeerConnectionInterface::SignalingState new_state =
      webrtc::PeerConnectionInterface::kHaveRemoteOffer;
  EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer));
  EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemoteOffer));
  pc_handler_->observer()->OnSignalingChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
  EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer));
  EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalPrAnswer));
  pc_handler_->observer()->OnSignalingChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kHaveLocalOffer;
  EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer));
  EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveLocalOffer));
  pc_handler_->observer()->OnSignalingChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
  EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer));
  EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
      WebRTCPeerConnectionHandlerClient::SignalingStateHaveRemotePrAnswer));
  pc_handler_->observer()->OnSignalingChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kClosed;
  EXPECT_CALL(*mock_tracker_.get(), TrackSignalingStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::SignalingStateClosed));
  EXPECT_CALL(*mock_client_.get(), didChangeSignalingState(
      WebRTCPeerConnectionHandlerClient::SignalingStateClosed));
  pc_handler_->observer()->OnSignalingChange(new_state);
}

TEST_F(RTCPeerConnectionHandlerTest, OnIceConnectionChange) {
  testing::InSequence sequence;

  webrtc::PeerConnectionInterface::IceConnectionState new_state =
      webrtc::PeerConnectionInterface::kIceConnectionNew;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateStarting));
  pc_handler_->observer()->OnIceConnectionChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceConnectionChecking;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateChecking));
  pc_handler_->observer()->OnIceConnectionChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceConnectionConnected;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateConnected));
  pc_handler_->observer()->OnIceConnectionChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceConnectionCompleted;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateCompleted));
  pc_handler_->observer()->OnIceConnectionChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceConnectionFailed;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateFailed));
  pc_handler_->observer()->OnIceConnectionChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateDisconnected));
  pc_handler_->observer()->OnIceConnectionChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceConnectionClosed;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceConnectionStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed));
  EXPECT_CALL(*mock_client_.get(), didChangeICEConnectionState(
      WebRTCPeerConnectionHandlerClient::ICEConnectionStateClosed));
  pc_handler_->observer()->OnIceConnectionChange(new_state);
}

TEST_F(RTCPeerConnectionHandlerTest, OnIceGatheringChange) {
  testing::InSequence sequence;
  EXPECT_CALL(*mock_tracker_.get(), TrackIceGatheringStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew));
  EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(
      WebRTCPeerConnectionHandlerClient::ICEGatheringStateNew));
  EXPECT_CALL(*mock_tracker_.get(), TrackIceGatheringStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering));
  EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(
      WebRTCPeerConnectionHandlerClient::ICEGatheringStateGathering));
  EXPECT_CALL(*mock_tracker_.get(), TrackIceGatheringStateChange(
      pc_handler_.get(),
      WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete));
  EXPECT_CALL(*mock_client_.get(), didChangeICEGatheringState(
      WebRTCPeerConnectionHandlerClient::ICEGatheringStateComplete));

  webrtc::PeerConnectionInterface::IceGatheringState new_state =
        webrtc::PeerConnectionInterface::kIceGatheringNew;
  pc_handler_->observer()->OnIceGatheringChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceGatheringGathering;
  pc_handler_->observer()->OnIceGatheringChange(new_state);

  new_state = webrtc::PeerConnectionInterface::kIceGatheringComplete;
  pc_handler_->observer()->OnIceGatheringChange(new_state);

  // Check NULL candidate after ice gathering is completed.
  EXPECT_EQ("", mock_client_->candidate_mid());
  EXPECT_EQ(-1, mock_client_->candidate_mlineindex());
  EXPECT_EQ("", mock_client_->candidate_sdp());
}

TEST_F(RTCPeerConnectionHandlerTest, OnAddAndOnRemoveStream) {
  std::string remote_stream_label("remote_stream");
  rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
      AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));

  testing::InSequence sequence;
  EXPECT_CALL(
      *mock_tracker_.get(),
      TrackAddStream(
          pc_handler_.get(),
          testing::Property(&blink::WebMediaStream::id,
                            blink::WebString::fromASCII(remote_stream_label)),
          PeerConnectionTracker::SOURCE_REMOTE));
  EXPECT_CALL(*mock_client_.get(),
              didAddRemoteStream(testing::Property(
                  &blink::WebMediaStream::id,
                  blink::WebString::fromASCII(remote_stream_label))));

  EXPECT_CALL(
      *mock_tracker_.get(),
      TrackRemoveStream(
          pc_handler_.get(),
          testing::Property(&blink::WebMediaStream::id,
                            blink::WebString::fromASCII(remote_stream_label)),
          PeerConnectionTracker::SOURCE_REMOTE));
  EXPECT_CALL(*mock_client_.get(),
              didRemoveRemoteStream(testing::Property(
                  &blink::WebMediaStream::id,
                  blink::WebString::fromASCII(remote_stream_label))));

  pc_handler_->observer()->OnAddStream(remote_stream);
  base::RunLoop().RunUntilIdle();
  pc_handler_->observer()->OnRemoveStream(remote_stream);
  base::RunLoop().RunUntilIdle();
}

// This test that WebKit is notified about remote track state changes.
TEST_F(RTCPeerConnectionHandlerTest, RemoteTrackState) {
  std::string remote_stream_label("remote_stream");
  rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
      AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));

  testing::InSequence sequence;
  EXPECT_CALL(*mock_client_.get(),
              didAddRemoteStream(testing::Property(
                  &blink::WebMediaStream::id,
                  blink::WebString::fromASCII(remote_stream_label))));
  pc_handler_->observer()->OnAddStream(remote_stream);
  base::RunLoop().RunUntilIdle();
  const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
  webkit_stream.audioTracks(audio_tracks);
  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
            audio_tracks[0].source().getReadyState());

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  webkit_stream.videoTracks(video_tracks);
  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
            video_tracks[0].source().getReadyState());

  static_cast<MockWebRtcAudioTrack*>(remote_stream->GetAudioTracks()[0].get())
      ->SetEnded();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
            audio_tracks[0].source().getReadyState());

  static_cast<MockWebRtcVideoTrack*>(remote_stream->GetVideoTracks()[0].get())
      ->SetEnded();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
            video_tracks[0].source().getReadyState());
}

TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
  std::string remote_stream_label("remote_stream");
  base::RunLoop run_loop;

  // Grab the added media stream when it's been successfully added to the PC.
  blink::WebMediaStream webkit_stream;
  EXPECT_CALL(*mock_client_.get(),
              didAddRemoteStream(testing::Property(
                  &blink::WebMediaStream::id,
                  blink::WebString::fromASCII(remote_stream_label))))
      .WillOnce(DoAll(SaveArg<0>(&webkit_stream),
                      ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));

  rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
      AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
  pc_handler_->observer()->OnAddStream(remote_stream);
  run_loop.Run();

  {
    // Test in a small scope so that  |audio_tracks| don't hold on to destroyed
    // source later.
    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
    webkit_stream.audioTracks(audio_tracks);
    EXPECT_EQ(1u, audio_tracks.size());
  }

  // Remove the Webrtc audio track from the Webrtc MediaStream.
  scoped_refptr<webrtc::AudioTrackInterface> webrtc_track =
      remote_stream->GetAudioTracks()[0].get();
  remote_stream->RemoveTrack(webrtc_track.get());
  base::RunLoop().RunUntilIdle();

  {
    blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks1;
    webkit_stream.audioTracks(modified_audio_tracks1);
    EXPECT_EQ(0u, modified_audio_tracks1.size());
  }

  blink::WebHeap::collectGarbageForTesting();

  // Add the WebRtc audio track again.
  remote_stream->AddTrack(webrtc_track.get());
  base::RunLoop().RunUntilIdle();
  blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks2;
  webkit_stream.audioTracks(modified_audio_tracks2);
  EXPECT_EQ(1u, modified_audio_tracks2.size());
}

TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
  std::string remote_stream_label("remote_stream");
  base::RunLoop run_loop;

  // Grab the added media stream when it's been successfully added to the PC.
  blink::WebMediaStream webkit_stream;
  EXPECT_CALL(*mock_client_.get(),
              didAddRemoteStream(testing::Property(
                  &blink::WebMediaStream::id,
                  blink::WebString::fromASCII(remote_stream_label))))
      .WillOnce(DoAll(SaveArg<0>(&webkit_stream),
                      ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));

  rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
      AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
  pc_handler_->observer()->OnAddStream(remote_stream);
  run_loop.Run();

  {
    // Test in a small scope so that  |video_tracks| don't hold on to destroyed
    // source later.
    blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
    webkit_stream.videoTracks(video_tracks);
    EXPECT_EQ(1u, video_tracks.size());
  }

  // Remove the Webrtc video track from the Webrtc MediaStream.
  scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
      remote_stream->GetVideoTracks()[0].get();
  remote_stream->RemoveTrack(webrtc_track.get());
  base::RunLoop().RunUntilIdle();
  {
    blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks1;
    webkit_stream.videoTracks(modified_video_tracks1);
    EXPECT_EQ(0u, modified_video_tracks1.size());
  }

  blink::WebHeap::collectGarbageForTesting();

  // Add the WebRtc video track again.
  remote_stream->AddTrack(webrtc_track.get());
  base::RunLoop().RunUntilIdle();
  blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks2;
  webkit_stream.videoTracks(modified_video_tracks2);
  EXPECT_EQ(1u, modified_video_tracks2.size());
}

TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddTracksFromRemoteStream) {
  std::string remote_stream_label("remote_stream");
  base::RunLoop run_loop;

  // Grab the added media stream when it's been successfully added to the PC.
  blink::WebMediaStream webkit_stream;
  EXPECT_CALL(*mock_client_.get(),
              didAddRemoteStream(testing::Property(
                  &blink::WebMediaStream::id,
                  blink::WebString::fromASCII(remote_stream_label))))
      .WillOnce(DoAll(SaveArg<0>(&webkit_stream),
                      ExitMessageLoop(&message_loop_, run_loop.QuitClosure())));

  rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
      AddRemoteMockMediaStream(remote_stream_label, "video", "audio"));
  pc_handler_->observer()->OnAddStream(remote_stream);
  run_loop.Run();

  {
    // Test in a small scope so that  |audio_tracks| don't hold on to destroyed
    // source later.
    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
    webkit_stream.audioTracks(audio_tracks);
    EXPECT_EQ(1u, audio_tracks.size());
    blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
    webkit_stream.videoTracks(video_tracks);
    EXPECT_EQ(1u, video_tracks.size());
  }

  // Remove the Webrtc tracks from the MediaStream.
  auto audio_track = remote_stream->GetAudioTracks()[0];
  EXPECT_TRUE(remote_stream->RemoveTrack(audio_track.get()));
  auto video_track = remote_stream->GetVideoTracks()[0];
  EXPECT_TRUE(remote_stream->RemoveTrack(video_track.get()));
  base::RunLoop().RunUntilIdle();

  {
    blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks;
    webkit_stream.audioTracks(modified_audio_tracks);
    EXPECT_EQ(0u, modified_audio_tracks.size());
    blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks;
    webkit_stream.videoTracks(modified_video_tracks);
    EXPECT_EQ(0u, modified_video_tracks.size());
  }

  blink::WebHeap::collectGarbageForTesting();

  // Add the tracks again.
  remote_stream->AddTrack(audio_track.get());
  base::RunLoop().RunUntilIdle();
  remote_stream->AddTrack(video_track.get());
  base::RunLoop().RunUntilIdle();

  blink::WebHeap::collectGarbageForTesting();

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
  webkit_stream.audioTracks(audio_tracks);
  EXPECT_EQ(1u, audio_tracks.size());
  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  webkit_stream.videoTracks(video_tracks);
  EXPECT_EQ(1u, video_tracks.size());
}

TEST_F(RTCPeerConnectionHandlerTest, OnIceCandidate) {
  testing::InSequence sequence;
  EXPECT_CALL(*mock_tracker_.get(),
              TrackAddIceCandidate(pc_handler_.get(), _,
                                   PeerConnectionTracker::SOURCE_LOCAL, true));
  EXPECT_CALL(*mock_client_.get(), didGenerateICECandidate(_));

  std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
      mock_dependency_factory_->CreateIceCandidate("sdpMid", 1, kDummySdp));
  pc_handler_->observer()->OnIceCandidate(native_candidate.get());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ("sdpMid", mock_client_->candidate_mid());
  EXPECT_EQ(1, mock_client_->candidate_mlineindex());
  EXPECT_EQ(kDummySdp, mock_client_->candidate_sdp());
}

TEST_F(RTCPeerConnectionHandlerTest, OnRenegotiationNeeded) {
  testing::InSequence sequence;
  EXPECT_CALL(*mock_tracker_.get(),
              TrackOnRenegotiationNeeded(pc_handler_.get()));
  EXPECT_CALL(*mock_client_.get(), negotiationNeeded());
  pc_handler_->observer()->OnRenegotiationNeeded();
}

TEST_F(RTCPeerConnectionHandlerTest, CreateDataChannel) {
  blink::WebString label = "d1";
  EXPECT_CALL(*mock_tracker_.get(),
              TrackCreateDataChannel(pc_handler_.get(),
                                     testing::NotNull(),
                                     PeerConnectionTracker::SOURCE_LOCAL));
  std::unique_ptr<blink::WebRTCDataChannelHandler> channel(
      pc_handler_->createDataChannel("d1", blink::WebRTCDataChannelInit()));
  EXPECT_TRUE(channel.get() != NULL);
  EXPECT_EQ(label, channel->label());
  channel->setClient(nullptr);
}

TEST_F(RTCPeerConnectionHandlerTest, CreateDtmfSender) {
  std::string stream_label = "local_stream";
  blink::WebMediaStream local_stream(CreateLocalMediaStream(stream_label));
  blink::WebMediaConstraints constraints;
  pc_handler_->addStream(local_stream, constraints);

  blink::WebVector<blink::WebMediaStreamTrack> tracks;
  local_stream.videoTracks(tracks);

  ASSERT_LE(1ul, tracks.size());
  EXPECT_FALSE(pc_handler_->createDTMFSender(tracks[0]));

  local_stream.audioTracks(tracks);
  ASSERT_LE(1ul, tracks.size());

  EXPECT_CALL(*mock_tracker_.get(),
              TrackCreateDTMFSender(pc_handler_.get(),
                                    testing::Ref(tracks[0])));

  std::unique_ptr<blink::WebRTCDTMFSenderHandler> sender(
      pc_handler_->createDTMFSender(tracks[0]));
  EXPECT_TRUE(sender.get());

  StopAllTracks(local_stream);
}

}  // namespace content
