// 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/user_media_client_impl.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "content/child/child_process.h"
#include "content/common/media/media_devices.h"
#include "content/renderer/media/media_stream_audio_processor_options.h"
#include "content/renderer/media/media_stream_audio_source.h"
#include "content/renderer/media/media_stream_constraints_util.h"
#include "content/renderer/media/media_stream_constraints_util_video_content.h"
#include "content/renderer/media/media_stream_track.h"
#include "content/renderer/media/mock_constraint_factory.h"
#include "content/renderer/media/mock_media_stream_dispatcher.h"
#include "content/renderer/media/mock_media_stream_video_source.h"
#include "content/renderer/media/mock_mojo_media_stream_dispatcher_host.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "media/audio/audio_device_description.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebMediaDeviceInfo.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/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebHeap.h"

using testing::_;

namespace content {

namespace {

blink::WebMediaConstraints CreateDefaultConstraints() {
  MockConstraintFactory factory;
  factory.AddAdvanced();
  return factory.CreateWebMediaConstraints();
}

blink::WebMediaConstraints CreateDeviceConstraints(
    const char* basic_exact_value,
    const char* basic_ideal_value = nullptr,
    const char* advanced_exact_value = nullptr) {
  MockConstraintFactory factory;
  if (basic_exact_value) {
    factory.basic().device_id.SetExact(
        blink::WebString::FromUTF8(basic_exact_value));
  }
  if (basic_ideal_value) {
    blink::WebString value = blink::WebString::FromUTF8(basic_ideal_value);
    factory.basic().device_id.SetIdeal(
        blink::WebVector<blink::WebString>(&value, 1));
  }

  auto& advanced = factory.AddAdvanced();
  if (advanced_exact_value) {
    blink::WebString value = blink::WebString::FromUTF8(advanced_exact_value);
    advanced.device_id.SetExact(value);
  }

  return factory.CreateWebMediaConstraints();
}

blink::WebMediaConstraints CreateFacingModeConstraints(
    const char* basic_exact_value,
    const char* basic_ideal_value = nullptr,
    const char* advanced_exact_value = nullptr) {
  MockConstraintFactory factory;
  if (basic_exact_value) {
    factory.basic().facing_mode.SetExact(
        blink::WebString::FromUTF8(basic_exact_value));
  }
  if (basic_ideal_value) {
    blink::WebString value = blink::WebString::FromUTF8(basic_ideal_value);
    factory.basic().device_id.SetIdeal(
        blink::WebVector<blink::WebString>(&value, 1));
  }

  auto& advanced = factory.AddAdvanced();
  if (advanced_exact_value) {
    blink::WebString value = blink::WebString::FromUTF8(advanced_exact_value);
    advanced.device_id.SetExact(value);
  }

  return factory.CreateWebMediaConstraints();
}

void CheckVideoSource(MediaStreamVideoSource* source,
                      int expected_source_width,
                      int expected_source_height,
                      double expected_source_frame_rate) {
  EXPECT_TRUE(source->IsRunning());
  EXPECT_TRUE(source->GetCurrentFormat().has_value());
  media::VideoCaptureFormat format = *source->GetCurrentFormat();
  EXPECT_EQ(format.frame_size.width(), expected_source_width);
  EXPECT_EQ(format.frame_size.height(), expected_source_height);
  EXPECT_EQ(format.frame_rate, expected_source_frame_rate);
}

void CheckVideoSourceAndTrack(MediaStreamVideoSource* source,
                              int expected_source_width,
                              int expected_source_height,
                              double expected_source_frame_rate,
                              const blink::WebMediaStreamTrack& web_track,
                              int expected_track_width,
                              int expected_track_height,
                              double expected_track_frame_rate) {
  CheckVideoSource(source, expected_source_width, expected_source_height,
                   expected_source_frame_rate);
  EXPECT_EQ(web_track.Source().GetReadyState(),
            blink::WebMediaStreamSource::kReadyStateLive);
  MediaStreamVideoTrack* track =
      MediaStreamVideoTrack::GetVideoTrack(web_track);
  EXPECT_EQ(track->source(), source);

  blink::WebMediaStreamTrack::Settings settings;
  track->GetSettings(settings);
  EXPECT_EQ(settings.width, expected_track_width);
  EXPECT_EQ(settings.height, expected_track_height);
  EXPECT_EQ(settings.frame_rate, expected_track_frame_rate);
}

class MockMediaStreamVideoCapturerSource : public MockMediaStreamVideoSource {
 public:
  MockMediaStreamVideoCapturerSource(const MediaStreamDevice& device,
                                     const SourceStoppedCallback& stop_callback,
                                     PeerConnectionDependencyFactory* factory)
      : MockMediaStreamVideoSource() {
    SetDevice(device);
    SetStopCallback(stop_callback);
  }
};

const char kInvalidDeviceId[] = "invalid";
const char kFakeAudioInputDeviceId1[] = "fake_audio_input 1";
const char kFakeAudioInputDeviceId2[] = "fake_audio_input 2";
const char kFakeVideoInputDeviceId1[] = "fake_video_input 1";
const char kFakeVideoInputDeviceId2[] = "fake_video_input 2";
const char kFakeAudioOutputDeviceId1[] = "fake_audio_output 1";

class MockMediaDevicesDispatcherHost
    : public ::mojom::MediaDevicesDispatcherHost {
 public:
  MockMediaDevicesDispatcherHost() {}
  void EnumerateDevices(bool request_audio_input,
                        bool request_video_input,
                        bool request_audio_output,
                        EnumerateDevicesCallback callback) override {
    std::vector<std::vector<MediaDeviceInfo>> result(NUM_MEDIA_DEVICE_TYPES);
    if (request_audio_input) {
      result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].push_back(MediaDeviceInfo(
          kFakeAudioInputDeviceId1, "Fake Audio Input 1", "fake_group 1"));
      result[MEDIA_DEVICE_TYPE_AUDIO_INPUT].push_back(MediaDeviceInfo(
          kFakeAudioInputDeviceId2, "Fake Audio Input 2", "fake_group 2"));
    }
    if (request_video_input) {
      result[MEDIA_DEVICE_TYPE_VIDEO_INPUT].push_back(
          MediaDeviceInfo(kFakeVideoInputDeviceId1, "Fake Video Input 1", ""));
      result[MEDIA_DEVICE_TYPE_VIDEO_INPUT].push_back(
          MediaDeviceInfo(kFakeVideoInputDeviceId2, "Fake Video Input 2", ""));
    }
    if (request_audio_output) {
      result[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT].push_back(MediaDeviceInfo(
          kFakeAudioOutputDeviceId1, "Fake Audio Input 1", "fake_group 1"));
    }
    std::move(callback).Run(result);
  }

  void GetVideoInputCapabilities(
      GetVideoInputCapabilitiesCallback client_callback) override {
    ::mojom::VideoInputDeviceCapabilitiesPtr device =
        ::mojom::VideoInputDeviceCapabilities::New();
    device->device_id = kFakeVideoInputDeviceId1;
    device->facing_mode = ::mojom::FacingMode::USER;
    if (!video_source_ || !video_source_->IsRunning() ||
        !video_source_->GetCurrentFormat()) {
      device->formats.push_back(media::VideoCaptureFormat(
          gfx::Size(640, 480), 30.0f, media::PIXEL_FORMAT_I420));
      device->formats.push_back(media::VideoCaptureFormat(
          gfx::Size(800, 600), 30.0f, media::PIXEL_FORMAT_I420));
      device->formats.push_back(media::VideoCaptureFormat(
          gfx::Size(1024, 768), 20.0f, media::PIXEL_FORMAT_I420));
    } else {
      device->formats.push_back(*video_source_->GetCurrentFormat());
    }
    std::vector<::mojom::VideoInputDeviceCapabilitiesPtr> result;
    result.push_back(std::move(device));

    device = ::mojom::VideoInputDeviceCapabilities::New();
    device->device_id = kFakeVideoInputDeviceId2;
    device->facing_mode = ::mojom::FacingMode::ENVIRONMENT;
    device->formats.push_back(media::VideoCaptureFormat(
        gfx::Size(640, 480), 30.0f, media::PIXEL_FORMAT_I420));
    result.push_back(std::move(device));

    std::move(client_callback).Run(std::move(result));
  }

  void GetAudioInputCapabilities(
      GetAudioInputCapabilitiesCallback client_callback) override {
    std::vector<::mojom::AudioInputDeviceCapabilitiesPtr> result;
    ::mojom::AudioInputDeviceCapabilitiesPtr device =
        ::mojom::AudioInputDeviceCapabilities::New();
    device->device_id = media::AudioDeviceDescription::kDefaultDeviceId;
    device->parameters = audio_parameters_;
    result.push_back(std::move(device));

    device = ::mojom::AudioInputDeviceCapabilities::New();
    device->device_id = kFakeAudioInputDeviceId1;
    device->parameters = audio_parameters_;
    result.push_back(std::move(device));

    device = ::mojom::AudioInputDeviceCapabilities::New();
    device->device_id = kFakeAudioInputDeviceId2;
    device->parameters = audio_parameters_;
    result.push_back(std::move(device));

    std::move(client_callback).Run(std::move(result));
  }

  media::AudioParameters& AudioParameters() { return audio_parameters_; }

  void ResetAudioParameters() {
    audio_parameters_ = media::AudioParameters::UnavailableDeviceParams();
  }

  MOCK_METHOD2(SubscribeDeviceChangeNotifications,
               void(MediaDeviceType type, uint32_t subscription_id));
  MOCK_METHOD2(UnsubscribeDeviceChangeNotifications,
               void(MediaDeviceType type, uint32_t subscription_id));

  void GetAllVideoInputDeviceFormats(
      const std::string&,
      GetAllVideoInputDeviceFormatsCallback callback) override {
    media::VideoCaptureFormats formats;
    formats.push_back(media::VideoCaptureFormat(gfx::Size(640, 480), 30.0f,
                                                media::PIXEL_FORMAT_I420));
    formats.push_back(media::VideoCaptureFormat(gfx::Size(800, 600), 30.0f,
                                                media::PIXEL_FORMAT_I420));
    formats.push_back(media::VideoCaptureFormat(gfx::Size(1024, 768), 20.0f,
                                                media::PIXEL_FORMAT_I420));
    std::move(callback).Run(formats);
  }

  void GetAvailableVideoInputDeviceFormats(
      const std::string& device_id,
      GetAvailableVideoInputDeviceFormatsCallback callback) override {
    if (!video_source_ || !video_source_->IsRunning() ||
        !video_source_->GetCurrentFormat()) {
      GetAllVideoInputDeviceFormats(device_id, std::move(callback));
      return;
    }

    media::VideoCaptureFormats formats;
    formats.push_back(*video_source_->GetCurrentFormat());
    std::move(callback).Run(formats);
  }

  void SetVideoSource(MediaStreamVideoSource* video_source) {
    video_source_ = video_source;
  }

 private:
  media::AudioParameters audio_parameters_ =
      media::AudioParameters::UnavailableDeviceParams();
  MediaStreamVideoSource* video_source_ = nullptr;
};

enum RequestState {
  REQUEST_NOT_STARTED,
  REQUEST_NOT_COMPLETE,
  REQUEST_SUCCEEDED,
  REQUEST_FAILED,
};

class UserMediaProcessorUnderTest : public UserMediaProcessor {
 public:
  UserMediaProcessorUnderTest(
      PeerConnectionDependencyFactory* dependency_factory,
      std::unique_ptr<MediaStreamDispatcher> media_stream_dispatcher,
      ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher,
      RequestState* state)
      : UserMediaProcessor(
            nullptr,
            dependency_factory,
            std::move(media_stream_dispatcher),
            base::BindRepeating(
                &UserMediaProcessorUnderTest::media_devices_dispatcher,
                base::Unretained(this)),
            base::ThreadTaskRunnerHandle::Get()),
        factory_(dependency_factory),
        media_devices_dispatcher_(std::move(media_devices_dispatcher)),
        state_(state) {}

  const ::mojom::MediaDevicesDispatcherHostPtr& media_devices_dispatcher()
      const {
    return media_devices_dispatcher_;
  }

  MockMediaStreamVideoCapturerSource* last_created_video_source() const {
    return video_source_;
  }
  void SetCreateSourceThatFails(bool should_fail) {
    create_source_that_fails_ = should_fail;
  }

  const blink::WebMediaStream& last_generated_stream() {
    return last_generated_stream_;
  }
  void ClearLastGeneratedStream() { last_generated_stream_.Reset(); }

  AudioCaptureSettings AudioSettings() const {
    return AudioCaptureSettingsForTesting();
  }
  VideoCaptureSettings VideoSettings() const {
    return VideoCaptureSettingsForTesting();
  }

  content::MediaStreamRequestResult error_reason() const { return result_; }
  blink::WebString constraint_name() const { return constraint_name_; }

  // UserMediaProcessor overrides.
  MediaStreamVideoSource* CreateVideoSource(
      const MediaStreamDevice& device,
      const MediaStreamSource::SourceStoppedCallback& stop_callback) override {
    video_source_ =
        new MockMediaStreamVideoCapturerSource(device, stop_callback, factory_);
    return video_source_;
  }

  MediaStreamAudioSource* CreateAudioSource(
      const MediaStreamDevice& device,
      const blink::WebMediaConstraints& constraints,
      const MediaStreamSource::ConstraintsCallback& source_ready,
      bool* has_sw_echo_cancellation) override {
    MediaStreamAudioSource* source;
    if (create_source_that_fails_) {
      class FailedAtLifeAudioSource : public MediaStreamAudioSource {
       public:
        FailedAtLifeAudioSource() : MediaStreamAudioSource(true) {}
        ~FailedAtLifeAudioSource() override {}

       protected:
        bool EnsureSourceIsStarted() override { return false; }
      };
      source = new FailedAtLifeAudioSource();
    } else {
      source = new MediaStreamAudioSource(true);
    }

    source->SetDevice(device);

    if (!create_source_that_fails_) {
      // RunUntilIdle is required for this task to complete.
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(&UserMediaProcessorUnderTest::SignalSourceReady,
                         source_ready, source));
    }

    *has_sw_echo_cancellation = false;
    return source;
  }

  void GetUserMediaRequestSucceeded(
      const blink::WebMediaStream& stream,
      blink::WebUserMediaRequest request_info) override {
    last_generated_stream_ = stream;
    *state_ = REQUEST_SUCCEEDED;
  }

  void GetUserMediaRequestFailed(
      content::MediaStreamRequestResult result,
      const blink::WebString& constraint_name) override {
    last_generated_stream_.Reset();
    *state_ = REQUEST_FAILED;
    result_ = result;
    constraint_name_ = constraint_name;
  }

 private:
  static void SignalSourceReady(
      const MediaStreamSource::ConstraintsCallback& source_ready,
      MediaStreamSource* source) {
    source_ready.Run(source, MEDIA_DEVICE_OK, "");
  }

  PeerConnectionDependencyFactory* factory_;
  ::mojom::MediaDevicesDispatcherHostPtr media_devices_dispatcher_;
  MockMediaStreamVideoCapturerSource* video_source_ = nullptr;
  bool create_source_that_fails_ = false;
  blink::WebMediaStream last_generated_stream_;
  content::MediaStreamRequestResult result_ = NUM_MEDIA_REQUEST_RESULTS;
  blink::WebString constraint_name_;
  RequestState* state_;
};

class UserMediaClientImplUnderTest : public UserMediaClientImpl {
 public:
  UserMediaClientImplUnderTest(UserMediaProcessor* user_media_processor,
                               RequestState* state)
      : UserMediaClientImpl(nullptr, base::WrapUnique(user_media_processor)),
        state_(state) {}

  void RequestUserMediaForTest(
      const blink::WebUserMediaRequest& user_media_request) {
    *state_ = REQUEST_NOT_COMPLETE;
    RequestUserMedia(user_media_request);
    base::RunLoop().RunUntilIdle();
  }

  void RequestUserMediaForTest() {
    blink::WebUserMediaRequest user_media_request =
        blink::WebUserMediaRequest::CreateForTesting(
            CreateDefaultConstraints(), CreateDefaultConstraints());
    RequestUserMediaForTest(user_media_request);
  }

  void RequestMediaDevicesForTest() {
    blink::WebMediaDevicesRequest media_devices_request;
    *state_ = REQUEST_NOT_COMPLETE;
    RequestMediaDevices(media_devices_request);
  }

  void EnumerateDevicesSucceded(
      blink::WebMediaDevicesRequest* request,
      blink::WebVector<blink::WebMediaDeviceInfo>& devices) override {
    *state_ = REQUEST_SUCCEEDED;
    last_devices_ = devices;
  }

  const blink::WebVector<blink::WebMediaDeviceInfo>& last_devices() {
    return last_devices_;
  }

 private:
  RequestState* state_;
  blink::WebVector<blink::WebMediaDeviceInfo> last_devices_;
};

}  // namespace

class UserMediaClientImplTest : public ::testing::Test {
 public:
  UserMediaClientImplTest()
      : binding_user_media_processor_(&media_devices_dispatcher_),
        binding_user_media_client_(&media_devices_dispatcher_),
        binding_event_dispatcher_(&media_devices_dispatcher_) {}

  void SetUp() override {
    // Create our test object.
    dependency_factory_.reset(new MockPeerConnectionDependencyFactory());

    ms_dispatcher_ = new MockMediaStreamDispatcher();
    mojom::MediaStreamDispatcherHostPtr dispatcher_host =
        mock_dispatcher_host_.CreateInterfacePtrAndBind();
    ms_dispatcher_->dispatcher_host_ = std::move(dispatcher_host);

    ::mojom::MediaDevicesDispatcherHostPtr user_media_processor_host_proxy;
    binding_user_media_processor_.Bind(
        mojo::MakeRequest(&user_media_processor_host_proxy));
    user_media_processor_ = new UserMediaProcessorUnderTest(
        dependency_factory_.get(), base::WrapUnique(ms_dispatcher_),
        std::move(user_media_processor_host_proxy), &state_),

    user_media_client_impl_ = std::make_unique<UserMediaClientImplUnderTest>(
        user_media_processor_, &state_);
    ::mojom::MediaDevicesDispatcherHostPtr user_media_client_host_proxy;
    binding_user_media_client_.Bind(
        mojo::MakeRequest(&user_media_client_host_proxy));
    user_media_client_impl_->SetMediaDevicesDispatcherForTesting(
        std::move(user_media_client_host_proxy));

    base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher =
        MediaDevicesEventDispatcher::GetForRenderFrame(nullptr);
    ::mojom::MediaDevicesDispatcherHostPtr event_dispatcher_host_proxy;
    binding_event_dispatcher_.Bind(
        mojo::MakeRequest(&event_dispatcher_host_proxy));
    event_dispatcher->SetMediaDevicesDispatcherForTesting(
        std::move(event_dispatcher_host_proxy));
  }

  void TearDown() override {
    MediaDevicesEventDispatcher::GetForRenderFrame(nullptr)->OnDestruct();
    user_media_client_impl_.reset();
    blink::WebHeap::CollectAllGarbageForTesting();
  }

  void LoadNewDocumentInFrame() {
    user_media_client_impl_->WillCommitProvisionalLoad();
  }

  blink::WebMediaStream RequestLocalMediaStream() {
    user_media_client_impl_->RequestUserMediaForTest();
    FakeMediaStreamDispatcherRequestUserMediaComplete();
    StartMockedVideoSource();

    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());

    blink::WebMediaStream desc = user_media_processor_->last_generated_stream();
    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
    desc.AudioTracks(audio_tracks);
    blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
    desc.VideoTracks(video_tracks);

    EXPECT_EQ(1u, audio_tracks.size());
    EXPECT_EQ(1u, video_tracks.size());
    EXPECT_NE(audio_tracks[0].Id(), video_tracks[0].Id());
    return desc;
  }

  blink::WebMediaStreamTrack RequestLocalVideoTrack() {
    blink::WebUserMediaRequest user_media_request =
        blink::WebUserMediaRequest::CreateForTesting(
            blink::WebMediaConstraints(), CreateDefaultConstraints());
    user_media_client_impl_->RequestUserMediaForTest(user_media_request);
    FakeMediaStreamDispatcherRequestUserMediaComplete();
    StartMockedVideoSource();
    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());

    blink::WebMediaStream web_stream =
        user_media_processor_->last_generated_stream();
    blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
    web_stream.AudioTracks(audio_tracks);
    blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
    web_stream.VideoTracks(video_tracks);

    EXPECT_EQ(audio_tracks.size(), 0U);
    EXPECT_EQ(video_tracks.size(), 1U);

    return video_tracks[0];
  }

  void FakeMediaStreamDispatcherRequestUserMediaComplete() {
    // Audio request ID is used as the shared request ID.
    user_media_processor_->OnStreamGenerated(
        ms_dispatcher_->audio_input_request_id(),
        ms_dispatcher_->stream_label(), ms_dispatcher_->audio_devices(),
        ms_dispatcher_->video_devices());
    base::RunLoop().RunUntilIdle();
  }

  void StartMockedVideoSource() {
    MockMediaStreamVideoCapturerSource* video_source =
        user_media_processor_->last_created_video_source();
    if (video_source->SourceHasAttemptedToStart())
      video_source->StartMockedSource();
  }

  void FailToStartMockedVideoSource() {
    MockMediaStreamVideoCapturerSource* video_source =
        user_media_processor_->last_created_video_source();
    if (video_source->SourceHasAttemptedToStart())
      video_source->FailToStartMockedSource();
    blink::WebHeap::CollectGarbageForTesting();
  }

  void TestValidRequestWithConstraints(
      const blink::WebMediaConstraints& audio_constraints,
      const blink::WebMediaConstraints& video_constraints,
      const std::string& expected_audio_device_id,
      const std::string& expected_video_device_id) {
    DCHECK(!audio_constraints.IsNull());
    DCHECK(!video_constraints.IsNull());
    blink::WebUserMediaRequest request =
        blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
                                                     video_constraints);
    user_media_client_impl_->RequestUserMediaForTest(request);
    FakeMediaStreamDispatcherRequestUserMediaComplete();
    StartMockedVideoSource();

    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
    EXPECT_EQ(1U, ms_dispatcher_->audio_devices().size());
    EXPECT_EQ(1U, ms_dispatcher_->video_devices().size());
    // MockMediaStreamDispatcher appends the session ID to its internal device
    // IDs.
    EXPECT_EQ(std::string(expected_audio_device_id) + "0",
              ms_dispatcher_->audio_devices()[0].id);
    EXPECT_EQ(std::string(expected_video_device_id) + "0",
              ms_dispatcher_->video_devices()[0].id);
  }

  void ApplyConstraintsVideoMode(
      const blink::WebMediaStreamTrack& web_track,
      int width,
      int height,
      const base::Optional<double>& frame_rate = base::Optional<double>()) {
    MockConstraintFactory factory;
    factory.basic().width.SetExact(width);
    factory.basic().height.SetExact(height);
    if (frame_rate)
      factory.basic().frame_rate.SetExact(*frame_rate);

    blink::WebApplyConstraintsRequest apply_constraints_request =
        blink::WebApplyConstraintsRequest::CreateForTesting(
            web_track, factory.CreateWebMediaConstraints());
    user_media_client_impl_->ApplyConstraints(apply_constraints_request);
    base::RunLoop().RunUntilIdle();
  }

  RequestState request_state() const { return state_; }

 protected:
  // The ScopedTaskEnvironment prevents the ChildProcess from leaking a
  // TaskScheduler.
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  ChildProcess child_process_;
  MockMediaStreamDispatcher* ms_dispatcher_ =
      nullptr;  // Owned by |used_media_processor_|.
  MockMojoMediaStreamDispatcherHost mock_dispatcher_host_;
  MockMediaDevicesDispatcherHost media_devices_dispatcher_;
  mojo::Binding<::mojom::MediaDevicesDispatcherHost>
      binding_user_media_processor_;
  mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_user_media_client_;
  mojo::Binding<::mojom::MediaDevicesDispatcherHost> binding_event_dispatcher_;

  UserMediaProcessorUnderTest* user_media_processor_ =
      nullptr;  // Owned by |user_media_client_impl_|
  std::unique_ptr<UserMediaClientImplUnderTest> user_media_client_impl_;
  std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
  RequestState state_ = REQUEST_NOT_STARTED;
};

TEST_F(UserMediaClientImplTest, GenerateMediaStream) {
  // Generate a stream with both audio and video.
  blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
}

// Test that the same source object is used if two MediaStreams are generated
// using the same source.
TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithSameSource) {
  blink::WebMediaStream desc1 = RequestLocalMediaStream();
  blink::WebMediaStream desc2 = RequestLocalMediaStream();

  blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
  desc1.VideoTracks(desc1_video_tracks);
  blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
  desc2.VideoTracks(desc2_video_tracks);
  EXPECT_EQ(desc1_video_tracks[0].Source().Id(),
            desc2_video_tracks[0].Source().Id());

  EXPECT_EQ(desc1_video_tracks[0].Source().GetExtraData(),
            desc2_video_tracks[0].Source().GetExtraData());

  blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
  desc1.AudioTracks(desc1_audio_tracks);
  blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
  desc2.AudioTracks(desc2_audio_tracks);
  EXPECT_EQ(desc1_audio_tracks[0].Source().Id(),
            desc2_audio_tracks[0].Source().Id());

  EXPECT_EQ(MediaStreamAudioSource::From(desc1_audio_tracks[0].Source()),
            MediaStreamAudioSource::From(desc2_audio_tracks[0].Source()));
}

// Test that the same source object is not used if two MediaStreams are
// generated using different sources.
TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
  blink::WebMediaStream desc1 = RequestLocalMediaStream();
  // Make sure another device is selected (another |session_id|) in  the next
  // gUM request.
  ms_dispatcher_->IncrementSessionId();
  blink::WebMediaStream desc2 = RequestLocalMediaStream();

  blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
  desc1.VideoTracks(desc1_video_tracks);
  blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
  desc2.VideoTracks(desc2_video_tracks);
  EXPECT_NE(desc1_video_tracks[0].Source().Id(),
            desc2_video_tracks[0].Source().Id());

  EXPECT_NE(desc1_video_tracks[0].Source().GetExtraData(),
            desc2_video_tracks[0].Source().GetExtraData());

  blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
  desc1.AudioTracks(desc1_audio_tracks);
  blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
  desc2.AudioTracks(desc2_audio_tracks);
  EXPECT_NE(desc1_audio_tracks[0].Source().Id(),
            desc2_audio_tracks[0].Source().Id());

  EXPECT_NE(MediaStreamAudioSource::From(desc1_audio_tracks[0].Source()),
            MediaStreamAudioSource::From(desc2_audio_tracks[0].Source()));
}

TEST_F(UserMediaClientImplTest, StopLocalTracks) {
  // Generate a stream with both audio and video.
  blink::WebMediaStream mixed_desc = RequestLocalMediaStream();

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
  mixed_desc.AudioTracks(audio_tracks);
  MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
  audio_track->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  mixed_desc.VideoTracks(video_tracks);
  MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
  video_track->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

// This test that a source is not stopped even if the tracks in a
// MediaStream is stopped if there are two MediaStreams with tracks using the
// same device. The source is stopped
// if there are no more MediaStream tracks using the device.
TEST_F(UserMediaClientImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
  // Generate a stream with both audio and video.
  blink::WebMediaStream desc1 = RequestLocalMediaStream();
  blink::WebMediaStream desc2 = RequestLocalMediaStream();

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1;
  desc1.AudioTracks(audio_tracks1);
  MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]);
  audio_track1->Stop();
  EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2;
  desc2.AudioTracks(audio_tracks2);
  MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]);
  audio_track2->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks1;
  desc1.VideoTracks(video_tracks1);
  MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]);
  video_track1->Stop();
  EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks2;
  desc2.VideoTracks(video_tracks2);
  MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]);
  video_track2->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

TEST_F(UserMediaClientImplTest, StopSourceWhenMediaStreamGoesOutOfScope) {
  // Generate a stream with both audio and video.
  RequestLocalMediaStream();
  // Makes sure the test itself don't hold a reference to the created
  // MediaStream.
  user_media_processor_->ClearLastGeneratedStream();
  blink::WebHeap::CollectAllGarbageForTesting();

  // Expect the sources to be stopped when the MediaStream goes out of scope.
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

// Test that the MediaStreams are deleted if a new document is loaded in the
// frame.
TEST_F(UserMediaClientImplTest, LoadNewDocumentInFrame) {
  // Test a stream with both audio and video.
  blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
  blink::WebMediaStream desc2 = RequestLocalMediaStream();
  LoadNewDocumentInFrame();
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

// This test what happens if a video source to a MediaSteam fails to start.
TEST_F(UserMediaClientImplTest, MediaVideoSourceFailToStart) {
  user_media_client_impl_->RequestUserMediaForTest();
  FakeMediaStreamDispatcherRequestUserMediaComplete();
  FailToStartMockedVideoSource();
  EXPECT_EQ(REQUEST_FAILED, request_state());
  EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
            user_media_processor_->error_reason());
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

// This test what happens if an audio source fail to initialize.
TEST_F(UserMediaClientImplTest, MediaAudioSourceFailToInitialize) {
  user_media_processor_->SetCreateSourceThatFails(true);
  user_media_client_impl_->RequestUserMediaForTest();
  FakeMediaStreamDispatcherRequestUserMediaComplete();
  StartMockedVideoSource();
  EXPECT_EQ(REQUEST_FAILED, request_state());
  EXPECT_EQ(MEDIA_DEVICE_TRACK_START_FAILURE,
            user_media_processor_->error_reason());
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

// This test what happens if UserMediaClientImpl is deleted before a source has
// started.
TEST_F(UserMediaClientImplTest, MediaStreamImplShutDown) {
  user_media_client_impl_->RequestUserMediaForTest();
  FakeMediaStreamDispatcherRequestUserMediaComplete();
  EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
  EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
  user_media_client_impl_.reset();
}

// This test what happens if a new document is loaded in the frame while the
// MediaStream is being generated by the MediaStreamDispatcher.
TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingStream) {
  user_media_client_impl_->RequestUserMediaForTest();
  LoadNewDocumentInFrame();
  EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
  EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(0, ms_dispatcher_->stop_video_device_counter());
  EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
}

// This test what happens if a newdocument is loaded in the frame while the
// sources are being started.
TEST_F(UserMediaClientImplTest, ReloadFrameWhileGeneratingSources) {
  user_media_client_impl_->RequestUserMediaForTest();
  FakeMediaStreamDispatcherRequestUserMediaComplete();
  EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
  LoadNewDocumentInFrame();
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
  EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
}

// This test what happens if stop is called on a track after the frame has
// been reloaded.
TEST_F(UserMediaClientImplTest, StopTrackAfterReload) {
  blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
  EXPECT_EQ(1, ms_dispatcher_->request_stream_counter());
  LoadNewDocumentInFrame();
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());

  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
  mixed_desc.AudioTracks(audio_tracks);
  MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
  audio_track->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());

  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  mixed_desc.VideoTracks(video_tracks);
  MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
  video_track->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
}

TEST_F(UserMediaClientImplTest, EnumerateMediaDevices) {
  user_media_client_impl_->RequestMediaDevicesForTest();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
  EXPECT_EQ(static_cast<size_t>(5),
            user_media_client_impl_->last_devices().size());

  // Audio input device with matched output ID.
  const blink::WebMediaDeviceInfo* device =
      &user_media_client_impl_->last_devices()[0];
  EXPECT_FALSE(device->DeviceId().IsEmpty());
  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput,
            device->Kind());
  EXPECT_FALSE(device->Label().IsEmpty());
  EXPECT_FALSE(device->GroupId().IsEmpty());

  // Audio input device without matched output ID.
  device = &user_media_client_impl_->last_devices()[1];
  EXPECT_FALSE(device->DeviceId().IsEmpty());
  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindAudioInput,
            device->Kind());
  EXPECT_FALSE(device->Label().IsEmpty());
  EXPECT_FALSE(device->GroupId().IsEmpty());

  // Video input devices.
  device = &user_media_client_impl_->last_devices()[2];
  EXPECT_FALSE(device->DeviceId().IsEmpty());
  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput,
            device->Kind());
  EXPECT_FALSE(device->Label().IsEmpty());
  EXPECT_TRUE(device->GroupId().IsEmpty());

  device = &user_media_client_impl_->last_devices()[3];
  EXPECT_FALSE(device->DeviceId().IsEmpty());
  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindVideoInput,
            device->Kind());
  EXPECT_FALSE(device->Label().IsEmpty());
  EXPECT_TRUE(device->GroupId().IsEmpty());

  // Audio output device.
  device = &user_media_client_impl_->last_devices()[4];
  EXPECT_FALSE(device->DeviceId().IsEmpty());
  EXPECT_EQ(blink::WebMediaDeviceInfo::kMediaDeviceKindAudioOutput,
            device->Kind());
  EXPECT_FALSE(device->Label().IsEmpty());
  EXPECT_FALSE(device->GroupId().IsEmpty());

  // Verfify group IDs.
  EXPECT_TRUE(user_media_client_impl_->last_devices()[0].GroupId().Equals(
      user_media_client_impl_->last_devices()[4].GroupId()));
  EXPECT_FALSE(user_media_client_impl_->last_devices()[1].GroupId().Equals(
      user_media_client_impl_->last_devices()[4].GroupId()));
}

TEST_F(UserMediaClientImplTest, DefaultConstraintsPropagate) {
  blink::WebUserMediaRequest request =
      blink::WebUserMediaRequest::CreateForTesting(CreateDefaultConstraints(),
                                                   CreateDefaultConstraints());
  user_media_client_impl_->RequestUserMediaForTest(request);
  AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  VideoCaptureSettings video_capture_settings =
      user_media_processor_->VideoSettings();
  user_media_client_impl_->CancelUserMediaRequest(request);

  // Check default values selected by the constraints algorithm.
  EXPECT_TRUE(audio_capture_settings.HasValue());
  EXPECT_EQ(media::AudioDeviceDescription::kDefaultDeviceId,
            audio_capture_settings.device_id());
  EXPECT_FALSE(audio_capture_settings.hotword_enabled());
  EXPECT_TRUE(audio_capture_settings.disable_local_echo());
  EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());

  const AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_TRUE(properties.enable_sw_echo_cancellation);
  EXPECT_FALSE(properties.disable_hw_echo_cancellation);
  EXPECT_FALSE(properties.goog_audio_mirroring);
  EXPECT_TRUE(properties.goog_auto_gain_control);
  // The default value for goog_experimental_echo_cancellation is platform
  // dependent.
  EXPECT_EQ(AudioProcessingProperties().goog_experimental_echo_cancellation,
            properties.goog_experimental_echo_cancellation);
  EXPECT_TRUE(properties.goog_typing_noise_detection);
  EXPECT_TRUE(properties.goog_noise_suppression);
  EXPECT_TRUE(properties.goog_experimental_noise_suppression);
  EXPECT_TRUE(properties.goog_beamforming);
  EXPECT_TRUE(properties.goog_highpass_filter);
  EXPECT_TRUE(properties.goog_experimental_auto_gain_control);
  EXPECT_TRUE(properties.goog_array_geometry.empty());

  EXPECT_TRUE(video_capture_settings.HasValue());
  EXPECT_EQ(video_capture_settings.Width(),
            MediaStreamVideoSource::kDefaultWidth);
  EXPECT_EQ(video_capture_settings.Height(),
            MediaStreamVideoSource::kDefaultHeight);
  EXPECT_EQ(video_capture_settings.FrameRate(),
            MediaStreamVideoSource::kDefaultFrameRate);
  EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
            media::RESOLUTION_POLICY_FIXED_RESOLUTION);
  EXPECT_EQ(video_capture_settings.PowerLineFrequency(),
            media::PowerLineFrequency::FREQUENCY_DEFAULT);
  EXPECT_FALSE(video_capture_settings.noise_reduction());
  EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());

  const VideoTrackAdapterSettings& track_settings =
      video_capture_settings.track_adapter_settings();
  EXPECT_EQ(track_settings.max_width, MediaStreamVideoSource::kDefaultWidth);
  EXPECT_EQ(track_settings.max_height, MediaStreamVideoSource::kDefaultHeight);
  EXPECT_EQ(track_settings.min_aspect_ratio,
            1.0 / MediaStreamVideoSource::kDefaultHeight);
  EXPECT_EQ(track_settings.max_aspect_ratio,
            MediaStreamVideoSource::kDefaultWidth);
  // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment
  EXPECT_EQ(track_settings.max_frame_rate, 0.0);
}

TEST_F(UserMediaClientImplTest, DefaultTabCapturePropagate) {
  MockConstraintFactory factory;
  factory.basic().media_stream_source.SetExact(
      blink::WebString::FromASCII(kMediaStreamSourceTab));
  blink::WebMediaConstraints audio_constraints =
      factory.CreateWebMediaConstraints();
  blink::WebMediaConstraints video_constraints =
      factory.CreateWebMediaConstraints();
  blink::WebUserMediaRequest request =
      blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
                                                   video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  VideoCaptureSettings video_capture_settings =
      user_media_processor_->VideoSettings();
  user_media_client_impl_->CancelUserMediaRequest(request);

  // Check default values selected by the constraints algorithm.
  EXPECT_TRUE(audio_capture_settings.HasValue());
  EXPECT_EQ(std::string(), audio_capture_settings.device_id());
  EXPECT_FALSE(audio_capture_settings.hotword_enabled());
  EXPECT_TRUE(audio_capture_settings.disable_local_echo());
  EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());

  const AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_FALSE(properties.enable_sw_echo_cancellation);
  EXPECT_FALSE(properties.disable_hw_echo_cancellation);
  EXPECT_FALSE(properties.goog_audio_mirroring);
  EXPECT_FALSE(properties.goog_auto_gain_control);
  EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
  EXPECT_FALSE(properties.goog_typing_noise_detection);
  EXPECT_FALSE(properties.goog_noise_suppression);
  EXPECT_FALSE(properties.goog_experimental_noise_suppression);
  EXPECT_FALSE(properties.goog_beamforming);
  EXPECT_FALSE(properties.goog_highpass_filter);
  EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
  EXPECT_TRUE(properties.goog_array_geometry.empty());

  EXPECT_TRUE(video_capture_settings.HasValue());
  EXPECT_EQ(video_capture_settings.Width(), kDefaultScreenCastWidth);
  EXPECT_EQ(video_capture_settings.Height(), kDefaultScreenCastHeight);
  EXPECT_EQ(video_capture_settings.FrameRate(), kDefaultScreenCastFrameRate);
  EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
            media::RESOLUTION_POLICY_FIXED_RESOLUTION);
  EXPECT_EQ(video_capture_settings.PowerLineFrequency(),
            media::PowerLineFrequency::FREQUENCY_DEFAULT);
  EXPECT_FALSE(video_capture_settings.noise_reduction());
  EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
  EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value());

  const VideoTrackAdapterSettings& track_settings =
      video_capture_settings.track_adapter_settings();
  EXPECT_EQ(track_settings.max_width, kDefaultScreenCastWidth);
  EXPECT_EQ(track_settings.max_height, kDefaultScreenCastHeight);
  EXPECT_EQ(track_settings.min_aspect_ratio, 1.0 / kMaxScreenCastDimension);
  EXPECT_EQ(track_settings.max_aspect_ratio, kMaxScreenCastDimension);
  // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment
  EXPECT_EQ(track_settings.max_frame_rate, 0.0);
}

TEST_F(UserMediaClientImplTest, DefaultDesktopCapturePropagate) {
  MockConstraintFactory factory;
  factory.basic().media_stream_source.SetExact(
      blink::WebString::FromASCII(kMediaStreamSourceDesktop));
  blink::WebMediaConstraints audio_constraints =
      factory.CreateWebMediaConstraints();
  blink::WebMediaConstraints video_constraints =
      factory.CreateWebMediaConstraints();
  blink::WebUserMediaRequest request =
      blink::WebUserMediaRequest::CreateForTesting(audio_constraints,
                                                   video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  VideoCaptureSettings video_capture_settings =
      user_media_processor_->VideoSettings();
  user_media_client_impl_->CancelUserMediaRequest(request);

  // Check default values selected by the constraints algorithm.
  EXPECT_TRUE(audio_capture_settings.HasValue());
  EXPECT_EQ(std::string(), audio_capture_settings.device_id());
  EXPECT_FALSE(audio_capture_settings.hotword_enabled());
  EXPECT_FALSE(audio_capture_settings.disable_local_echo());
  EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());

  const AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_FALSE(properties.enable_sw_echo_cancellation);
  EXPECT_FALSE(properties.disable_hw_echo_cancellation);
  EXPECT_FALSE(properties.goog_audio_mirroring);
  EXPECT_FALSE(properties.goog_auto_gain_control);
  EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
  EXPECT_FALSE(properties.goog_typing_noise_detection);
  EXPECT_FALSE(properties.goog_noise_suppression);
  EXPECT_FALSE(properties.goog_experimental_noise_suppression);
  EXPECT_FALSE(properties.goog_beamforming);
  EXPECT_FALSE(properties.goog_highpass_filter);
  EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
  EXPECT_TRUE(properties.goog_array_geometry.empty());

  EXPECT_TRUE(video_capture_settings.HasValue());
  EXPECT_EQ(video_capture_settings.Width(), kDefaultScreenCastWidth);
  EXPECT_EQ(video_capture_settings.Height(), kDefaultScreenCastHeight);
  EXPECT_EQ(video_capture_settings.FrameRate(), kDefaultScreenCastFrameRate);
  EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
            media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT);
  EXPECT_EQ(video_capture_settings.PowerLineFrequency(),
            media::PowerLineFrequency::FREQUENCY_DEFAULT);
  EXPECT_FALSE(video_capture_settings.noise_reduction());
  EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
  EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value());

  const VideoTrackAdapterSettings& track_settings =
      video_capture_settings.track_adapter_settings();
  EXPECT_EQ(track_settings.max_width, kDefaultScreenCastWidth);
  EXPECT_EQ(track_settings.max_height, kDefaultScreenCastHeight);
  EXPECT_EQ(track_settings.min_aspect_ratio, 1.0 / kMaxScreenCastDimension);
  EXPECT_EQ(track_settings.max_aspect_ratio, kMaxScreenCastDimension);
  // 0.0 is the default max_frame_rate and it indicates no frame-rate adjustment
  EXPECT_EQ(track_settings.max_frame_rate, 0.0);
}

TEST_F(UserMediaClientImplTest, NonDefaultAudioConstraintsPropagate) {
  MockConstraintFactory factory;
  factory.basic().device_id.SetExact(
      blink::WebString::FromASCII(kFakeAudioInputDeviceId1));
  factory.basic().hotword_enabled.SetExact(true);
  factory.basic().disable_local_echo.SetExact(true);
  factory.basic().render_to_associated_sink.SetExact(true);
  factory.basic().echo_cancellation.SetExact(false);
  factory.basic().goog_audio_mirroring.SetExact(true);
  factory.basic().goog_typing_noise_detection.SetExact(true);
  factory.basic().goog_array_geometry.SetExact(
      blink::WebString::FromASCII("1 1 1"));
  blink::WebMediaConstraints audio_constraints =
      factory.CreateWebMediaConstraints();
  // Request contains only audio
  blink::WebUserMediaRequest request =
      blink::WebUserMediaRequest::CreateForTesting(
          audio_constraints, blink::WebMediaConstraints());
  user_media_client_impl_->RequestUserMediaForTest(request);
  AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  VideoCaptureSettings video_capture_settings =
      user_media_processor_->VideoSettings();
  user_media_client_impl_->CancelUserMediaRequest(request);

  EXPECT_FALSE(video_capture_settings.HasValue());

  EXPECT_TRUE(audio_capture_settings.HasValue());
  EXPECT_EQ(kFakeAudioInputDeviceId1, audio_capture_settings.device_id());
  EXPECT_TRUE(audio_capture_settings.hotword_enabled());
  EXPECT_TRUE(audio_capture_settings.disable_local_echo());
  EXPECT_TRUE(audio_capture_settings.render_to_associated_sink());

  const AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_FALSE(properties.enable_sw_echo_cancellation);
  EXPECT_TRUE(properties.disable_hw_echo_cancellation);
  EXPECT_TRUE(properties.goog_audio_mirroring);
  EXPECT_FALSE(properties.goog_auto_gain_control);
  EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
  EXPECT_TRUE(properties.goog_typing_noise_detection);
  EXPECT_FALSE(properties.goog_noise_suppression);
  EXPECT_FALSE(properties.goog_experimental_noise_suppression);
  EXPECT_FALSE(properties.goog_beamforming);
  EXPECT_FALSE(properties.goog_highpass_filter);
  EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
  const std::vector<media::Point> kGeometry = {{1.0, 1.0, 1.0}};
  EXPECT_EQ(kGeometry, properties.goog_array_geometry);
}

TEST_F(UserMediaClientImplTest, ObserveMediaDeviceChanges) {
  EXPECT_CALL(media_devices_dispatcher_, SubscribeDeviceChangeNotifications(
                                             MEDIA_DEVICE_TYPE_AUDIO_INPUT, _));
  EXPECT_CALL(media_devices_dispatcher_, SubscribeDeviceChangeNotifications(
                                             MEDIA_DEVICE_TYPE_VIDEO_INPUT, _));
  EXPECT_CALL(
      media_devices_dispatcher_,
      SubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, _));
  user_media_client_impl_->SetMediaDeviceChangeObserver(
      blink::WebMediaDeviceChangeObserver(true));
  base::RunLoop().RunUntilIdle();

  base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher =
      MediaDevicesEventDispatcher::GetForRenderFrame(nullptr);
  event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_AUDIO_INPUT,
                                                MediaDeviceInfoArray());
  event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_VIDEO_INPUT,
                                                MediaDeviceInfoArray());
  event_dispatcher->DispatchDevicesChangedEvent(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT,
                                                MediaDeviceInfoArray());
  base::RunLoop().RunUntilIdle();

  EXPECT_CALL(media_devices_dispatcher_, UnsubscribeDeviceChangeNotifications(
                                             MEDIA_DEVICE_TYPE_AUDIO_INPUT, _));
  EXPECT_CALL(media_devices_dispatcher_, UnsubscribeDeviceChangeNotifications(
                                             MEDIA_DEVICE_TYPE_VIDEO_INPUT, _));
  EXPECT_CALL(
      media_devices_dispatcher_,
      UnsubscribeDeviceChangeNotifications(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, _));

  user_media_client_impl_->SetMediaDeviceChangeObserver(
      blink::WebMediaDeviceChangeObserver());
  base::RunLoop().RunUntilIdle();
}

// This test what happens if the audio stream has same id with video stream.
TEST_F(UserMediaClientImplTest, AudioVideoWithSameId) {
  ms_dispatcher_->TestSameId();

  // Generate a stream with both audio and video.
  blink::WebMediaStream mixed_desc = RequestLocalMediaStream();

  // Remove video track. This should trigger
  // UserMediaClientImpl::OnLocalSourceStopped, and has video track to be
  // removed from its |local_sources_|.
  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
  mixed_desc.VideoTracks(video_tracks);
  MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
  video_track->Stop();
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
  EXPECT_EQ(0, ms_dispatcher_->stop_audio_device_counter());

  // Now we load a new document in the web frame. If in the above Stop() call,
  // UserMediaClientImpl accidentally removed audio track, then video track will
  // be removed again here, which is incorrect.
  LoadNewDocumentInFrame();
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, ms_dispatcher_->stop_video_device_counter());
  EXPECT_EQ(1, ms_dispatcher_->stop_audio_device_counter());
}

TEST_F(UserMediaClientImplTest, CreateWithMandatoryInvalidAudioDeviceId) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(kInvalidDeviceId);
  blink::WebUserMediaRequest request =
      blink::WebUserMediaRequest::CreateForTesting(
          audio_constraints, blink::WebMediaConstraints());
  user_media_client_impl_->RequestUserMediaForTest(request);
  EXPECT_EQ(REQUEST_FAILED, request_state());
}

TEST_F(UserMediaClientImplTest, CreateWithMandatoryInvalidVideoDeviceId) {
  blink::WebMediaConstraints video_constraints =
      CreateDeviceConstraints(kInvalidDeviceId);
  blink::WebUserMediaRequest request =
      blink::WebUserMediaRequest::CreateForTesting(blink::WebMediaConstraints(),
                                                   video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  EXPECT_EQ(REQUEST_FAILED, request_state());
}

TEST_F(UserMediaClientImplTest, CreateWithMandatoryValidDeviceIds) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(kFakeAudioInputDeviceId1);
  blink::WebMediaConstraints video_constraints =
      CreateDeviceConstraints(kFakeVideoInputDeviceId1);
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientImplTest, CreateWithBasicIdealValidDeviceId) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(nullptr, kFakeAudioInputDeviceId1);
  blink::WebMediaConstraints video_constraints =
      CreateDeviceConstraints(nullptr, kFakeVideoInputDeviceId1);
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientImplTest, CreateWithAdvancedExactValidDeviceId) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(nullptr, nullptr, kFakeAudioInputDeviceId1);
  blink::WebMediaConstraints video_constraints =
      CreateDeviceConstraints(nullptr, nullptr, kFakeVideoInputDeviceId1);
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientImplTest, CreateWithAllOptionalInvalidDeviceId) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
  blink::WebMediaConstraints video_constraints =
      CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
  // MockMediaStreamDispatcher uses empty string as default audio device ID.
  // MockMediaDevicesDispatcher uses the first device in the enumeration as
  // default audio or video device ID.
  std::string expected_audio_device_id =
      media::AudioDeviceDescription::kDefaultDeviceId;
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  expected_audio_device_id,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientImplTest, CreateWithFacingModeUser) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(kFakeAudioInputDeviceId1);
  blink::WebMediaConstraints video_constraints =
      CreateFacingModeConstraints("user");
  // kFakeVideoInputDeviceId1 has user facing mode.
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientImplTest, CreateWithFacingModeEnvironment) {
  blink::WebMediaConstraints audio_constraints =
      CreateDeviceConstraints(kFakeAudioInputDeviceId1);
  blink::WebMediaConstraints video_constraints =
      CreateFacingModeConstraints("environment");
  // kFakeVideoInputDeviceId2 has environment facing mode.
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId2);
}

TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceSingleTrack) {
  EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
  blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
  MediaStreamVideoTrack* track =
      MediaStreamVideoTrack::GetVideoTrack(web_track);
  MediaStreamVideoSource* source = track->source();
  CheckVideoSource(source, 0, 0, 0.0);

  media_devices_dispatcher_.SetVideoSource(source);

  // The following applyConstraint() request should force a source restart and
  // produce a video mode with 1024x768.
  ApplyConstraintsVideoMode(web_track, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 1024, 768, 20.0);

  // The following applyConstraints() requests should not result in a source
  // restart since the only format supported by the mock MDDH that supports
  // 801x600 is the existing 1024x768 mode with downscaling.
  ApplyConstraintsVideoMode(web_track, 801, 600);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 801, 600, 20.0);

  // The following applyConstraints() requests should result in a source restart
  // since there is a native mode of 800x600 supported by the mock MDDH.
  ApplyConstraintsVideoMode(web_track, 800, 600);
  CheckVideoSourceAndTrack(source, 800, 600, 30.0, web_track, 800, 600, 30.0);

  // The following applyConstraints() requests should fail since the mock MDDH
  // does not have any mode that can produce 2000x2000.
  ApplyConstraintsVideoMode(web_track, 2000, 2000);
  CheckVideoSourceAndTrack(source, 800, 600, 30.0, web_track, 800, 600, 30.0);
}

TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceTwoTracks) {
  EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
  blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
  MockMediaStreamVideoCapturerSource* source =
      user_media_processor_->last_created_video_source();
  CheckVideoSource(source, 0, 0, 0.0);
  media_devices_dispatcher_.SetVideoSource(source);

  // Switch the source and track to 1024x768@20Hz.
  ApplyConstraintsVideoMode(web_track, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 1024, 768, 20.0);

  // Create a new track and verify that it uses the same source and that the
  // source's format did not change. The new track uses the same format as the
  // source by default.
  EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
  blink::WebMediaStreamTrack web_track2 = RequestLocalVideoTrack();
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track2, 1024, 768,
                           20.0);

  // Use applyConstraints() to change the first track to 800x600 and verify
  // that the source is not reconfigured. Downscaling is used instead because
  // there is more than one track using the source. The second track is left
  // unmodified.
  ApplyConstraintsVideoMode(web_track, 800, 600);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 800, 600, 20.0);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track2, 1024, 768,
                           20.0);

  // Try to use applyConstraints() to change the first track to 800x600@30Hz.
  // It fails, because the source is open in native 20Hz mode and it does not
  // support reconfiguration when more than one track is connected.
  // TODO(guidou): Allow reconfiguring sources with more than one track.
  // http://crbug.com/768205.
  ApplyConstraintsVideoMode(web_track, 800, 600, 30.0);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 800, 600, 20.0);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track2, 1024, 768,
                           20.0);

  // Try to use applyConstraints() to change the first track to 800x600@30Hz.
  // after stopping the second track. In this case, the source is left with a
  // single track and it supports reconfiguration to the requested mode.
  MediaStreamTrack::GetTrack(web_track2)->Stop();
  ApplyConstraintsVideoMode(web_track, 800, 600, 30.0);
  CheckVideoSourceAndTrack(source, 800, 600, 30.0, web_track, 800, 600, 30.0);
}

TEST_F(UserMediaClientImplTest,
       ApplyConstraintsVideoDeviceFailsToStopForRestart) {
  EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
  blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
  MockMediaStreamVideoCapturerSource* source =
      user_media_processor_->last_created_video_source();
  CheckVideoSource(source, 0, 0, 0.0);
  media_devices_dispatcher_.SetVideoSource(source);

  // Switch the source and track to 1024x768@20Hz.
  ApplyConstraintsVideoMode(web_track, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 1024, 768, 20.0);

  // Try to switch the source and track to 640x480. Since the source cannot
  // stop for restart, downscaling is used for the track.
  source->DisableStopForRestart();
  ApplyConstraintsVideoMode(web_track, 640, 480);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 640, 480, 20.0);
}

TEST_F(UserMediaClientImplTest,
       ApplyConstraintsVideoDeviceFailsToRestartAfterStop) {
  EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
  blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
  MockMediaStreamVideoCapturerSource* source =
      user_media_processor_->last_created_video_source();
  CheckVideoSource(source, 0, 0, 0.0);
  media_devices_dispatcher_.SetVideoSource(source);

  // Switch the source and track to 1024x768.
  ApplyConstraintsVideoMode(web_track, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 1024, 768, 20.0);

  // Try to switch the source and track to 640x480. Since the source cannot
  // restart, source and track are stopped.
  source->DisableRestart();
  ApplyConstraintsVideoMode(web_track, 640, 480);

  EXPECT_EQ(web_track.Source().GetReadyState(),
            blink::WebMediaStreamSource::kReadyStateEnded);
  EXPECT_FALSE(source->IsRunning());
}

TEST_F(UserMediaClientImplTest, ApplyConstraintsVideoDeviceStopped) {
  EXPECT_CALL(mock_dispatcher_host_, StreamStarted(_));
  blink::WebMediaStreamTrack web_track = RequestLocalVideoTrack();
  MockMediaStreamVideoCapturerSource* source =
      user_media_processor_->last_created_video_source();
  CheckVideoSource(source, 0, 0, 0.0);
  media_devices_dispatcher_.SetVideoSource(source);

  // Switch the source and track to 1024x768.
  ApplyConstraintsVideoMode(web_track, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, web_track, 1024, 768, 20.0);

  // Try to switch the source and track to 640x480 after stopping the track.
  MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
  track->Stop();
  EXPECT_EQ(web_track.Source().GetReadyState(),
            blink::WebMediaStreamSource::kReadyStateEnded);
  EXPECT_FALSE(source->IsRunning());
  {
    blink::WebMediaStreamTrack::Settings settings;
    track->GetSettings(settings);
    EXPECT_EQ(settings.width, -1);
    EXPECT_EQ(settings.height, -1);
    EXPECT_EQ(settings.frame_rate, -1.0);
  }

  ApplyConstraintsVideoMode(web_track, 640, 480);
  EXPECT_EQ(web_track.Source().GetReadyState(),
            blink::WebMediaStreamSource::kReadyStateEnded);
  EXPECT_FALSE(source->IsRunning());
  {
    blink::WebMediaStreamTrack::Settings settings;
    track->GetSettings(settings);
    EXPECT_EQ(settings.width, -1);
    EXPECT_EQ(settings.height, -1);
    EXPECT_EQ(settings.frame_rate, -1.0);
  }
}

}  // namespace content
