// 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 "third_party/blink/renderer/modules/mediastream/user_media_client.h"

#include <stddef.h>

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

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "media/audio/audio_device_description.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/mediastream/media_devices.h"
#include "third_party/blink/public/common/widget/screen_info.h"
#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_source.h"
#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_track.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h"
#include "third_party/blink/public/web/web_heap.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
#include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h"
#include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
#include "third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h"
#include "third_party/blink/renderer/platform/mediastream/media_stream_track_platform.h"
#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

using testing::_;
using testing::Mock;

namespace blink {

using EchoCancellationType =
    blink::AudioProcessingProperties::EchoCancellationType;

namespace {

MediaConstraints CreateDefaultConstraints() {
  blink::MockConstraintFactory factory;
  factory.AddAdvanced();
  return factory.CreateMediaConstraints();
}

MediaConstraints CreateDeviceConstraints(
    const char* basic_exact_value,
    const char* basic_ideal_value = nullptr,
    const char* advanced_exact_value = nullptr) {
  blink::MockConstraintFactory factory;
  if (basic_exact_value) {
    factory.basic().device_id.SetExact(basic_exact_value);
  }
  if (basic_ideal_value) {
    factory.basic().device_id.SetIdeal(Vector<String>({basic_ideal_value}));
  }

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

  return factory.CreateMediaConstraints();
}

MediaConstraints CreateFacingModeConstraints(
    const char* basic_exact_value,
    const char* basic_ideal_value = nullptr,
    const char* advanced_exact_value = nullptr) {
  blink::MockConstraintFactory factory;
  if (basic_exact_value) {
    factory.basic().facing_mode.SetExact(String::FromUTF8(basic_exact_value));
  }
  if (basic_ideal_value) {
    factory.basic().device_id.SetIdeal(Vector<String>({basic_ideal_value}));
  }

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

  return factory.CreateMediaConstraints();
}

void CheckVideoSource(blink::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(blink::MediaStreamVideoSource* source,
                              int expected_source_width,
                              int expected_source_height,
                              double expected_source_frame_rate,
                              MediaStreamComponent* component,
                              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(component->Source()->GetReadyState(),
            MediaStreamSource::kReadyStateLive);
  MediaStreamVideoTrack* track = MediaStreamVideoTrack::From(component);
  EXPECT_EQ(track->source(), source);

  MediaStreamTrackPlatform::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 MockLocalMediaStreamAudioSource : public blink::MediaStreamAudioSource {
 public:
  MockLocalMediaStreamAudioSource()
      : blink::MediaStreamAudioSource(
            blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
            true /* is_local_source */) {}

  MOCK_METHOD0(EnsureSourceIsStopped, void());

  void ChangeSourceImpl(const blink::MediaStreamDevice& new_device) {
    EnsureSourceIsStopped();
  }
};

class MockMediaStreamVideoCapturerSource
    : public blink::MockMediaStreamVideoSource {
 public:
  MockMediaStreamVideoCapturerSource(const blink::MediaStreamDevice& device,
                                     SourceStoppedCallback stop_callback)
      : blink::MockMediaStreamVideoSource() {
    SetDevice(device);
    SetStopCallback(std::move(stop_callback));
  }

  MOCK_METHOD1(ChangeSourceImpl,
               void(const blink::MediaStreamDevice& new_device));
};

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";

class MockMediaDevicesDispatcherHost
    : public mojom::blink::MediaDevicesDispatcherHost {
 public:
  MockMediaDevicesDispatcherHost() {}
  void EnumerateDevices(bool request_audio_input,
                        bool request_video_input,
                        bool request_audio_output,
                        bool request_video_input_capabilities,
                        bool request_audio_input_capabilities,
                        EnumerateDevicesCallback callback) override {
    NOTREACHED();
  }

  void GetVideoInputCapabilities(
      GetVideoInputCapabilitiesCallback client_callback) override {
    blink::mojom::blink::VideoInputDeviceCapabilitiesPtr device =
        blink::mojom::blink::VideoInputDeviceCapabilities::New();
    device->device_id = kFakeVideoInputDeviceId1;
    device->group_id = String("dummy");
    device->facing_mode = mojom::blink::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());
    }
    Vector<blink::mojom::blink::VideoInputDeviceCapabilitiesPtr> result;
    result.push_back(std::move(device));

    device = blink::mojom::blink::VideoInputDeviceCapabilities::New();
    device->device_id = kFakeVideoInputDeviceId2;
    device->group_id = String("dummy");
    device->facing_mode = mojom::blink::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 {
    Vector<blink::mojom::blink::AudioInputDeviceCapabilitiesPtr> result;
    blink::mojom::blink::AudioInputDeviceCapabilitiesPtr device =
        blink::mojom::blink::AudioInputDeviceCapabilities::New();
    device->device_id = media::AudioDeviceDescription::kDefaultDeviceId;
    device->group_id = String("dummy");
    device->parameters = audio_parameters_;
    result.push_back(std::move(device));

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

    device = blink::mojom::blink::AudioInputDeviceCapabilities::New();
    device->device_id = kFakeAudioInputDeviceId2;
    device->group_id = String("dummy");
    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();
  }

  void AddMediaDevicesListener(
      bool subscribe_audio_input,
      bool subscribe_video_input,
      bool subscribe_audio_output,
      mojo::PendingRemote<blink::mojom::blink::MediaDevicesListener> listener)
      override {
    NOTREACHED();
  }

  void GetAllVideoInputDeviceFormats(
      const String&,
      GetAllVideoInputDeviceFormatsCallback callback) override {
    Vector<media::VideoCaptureFormat> 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 String& device_id,
      GetAvailableVideoInputDeviceFormatsCallback callback) override {
    if (!video_source_ || !video_source_->IsRunning() ||
        !video_source_->GetCurrentFormat()) {
      GetAllVideoInputDeviceFormats(device_id, std::move(callback));
      return;
    }

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

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

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

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

class UserMediaProcessorUnderTest : public UserMediaProcessor {
 public:
  UserMediaProcessorUnderTest(
      LocalFrame* frame,
      std::unique_ptr<blink::WebMediaStreamDeviceObserver>
          media_stream_device_observer,
      mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost>
          media_devices_dispatcher,
      RequestState* state)
      : UserMediaProcessor(
            frame,
            base::BindRepeating(
                &UserMediaProcessorUnderTest::media_devices_dispatcher,
                base::Unretained(this)),
            blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
        media_stream_device_observer_(std::move(media_stream_device_observer)),
        media_devices_dispatcher_(std::move(media_devices_dispatcher)),
        state_(state) {
    SetMediaStreamDeviceObserverForTesting(media_stream_device_observer_.get());
  }

  blink::mojom::blink::MediaDevicesDispatcherHost* media_devices_dispatcher()
      const {
    return media_devices_dispatcher_.get();
  }

  MockMediaStreamVideoCapturerSource* last_created_video_source() const {
    return video_source_;
  }
  MockLocalMediaStreamAudioSource* last_created_local_audio_source() const {
    return local_audio_source_;
  }

  void SetCreateSourceThatFails(bool should_fail) {
    create_source_that_fails_ = should_fail;
  }

  MediaStreamDescriptor* last_generated_descriptor() {
    return last_generated_descriptor_;
  }
  void ClearLastGeneratedStream() { last_generated_descriptor_ = nullptr; }

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

  blink::mojom::blink::MediaStreamRequestResult error_reason() const {
    return result_;
  }
  String constraint_name() const { return constraint_name_; }

  // UserMediaProcessor overrides.
  std::unique_ptr<blink::MediaStreamVideoSource> CreateVideoSource(
      const blink::MediaStreamDevice& device,
      blink::WebPlatformMediaStreamSource::SourceStoppedCallback stop_callback)
      override {
    video_source_ = new MockMediaStreamVideoCapturerSource(
        device, std::move(stop_callback));
    return base::WrapUnique(video_source_);
  }

  std::unique_ptr<blink::MediaStreamAudioSource> CreateAudioSource(
      const blink::MediaStreamDevice& device,
      blink::WebPlatformMediaStreamSource::ConstraintsRepeatingCallback
          source_ready) override {
    std::unique_ptr<blink::MediaStreamAudioSource> source;
    if (create_source_that_fails_) {
      class FailedAtLifeAudioSource : public blink::MediaStreamAudioSource {
       public:
        FailedAtLifeAudioSource()
            : blink::MediaStreamAudioSource(
                  blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
                  true) {}
        ~FailedAtLifeAudioSource() override {}

       protected:
        bool EnsureSourceIsStarted() override { return false; }
      };
      source = std::make_unique<FailedAtLifeAudioSource>();
    } else if (blink::IsDesktopCaptureMediaType(device.type)) {
      local_audio_source_ = new MockLocalMediaStreamAudioSource();
      source = base::WrapUnique(local_audio_source_);
    } else {
      source = std::make_unique<blink::MediaStreamAudioSource>(
          blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true);
    }

    source->SetDevice(device);

    if (!create_source_that_fails_) {
      // RunUntilIdle is required for this task to complete.
      blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostTask(
          FROM_HERE,
          base::BindOnce(&UserMediaProcessorUnderTest::SignalSourceReady,
                         std::move(source_ready), source.get()));
    }

    return source;
  }

  void GetUserMediaRequestSucceeded(MediaStreamDescriptor* descriptor,
                                    UserMediaRequest* request_info) override {
    last_generated_descriptor_ = descriptor;
    *state_ = REQUEST_SUCCEEDED;
  }

  void GetUserMediaRequestFailed(
      blink::mojom::blink::MediaStreamRequestResult result,
      const String& constraint_name) override {
    last_generated_descriptor_ = nullptr;
    *state_ = REQUEST_FAILED;
    result_ = result;
    constraint_name_ = constraint_name;
  }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(last_generated_descriptor_);
    UserMediaProcessor::Trace(visitor);
  }

 private:
  static void SignalSourceReady(
      blink::WebPlatformMediaStreamSource::ConstraintsOnceCallback source_ready,
      blink::WebPlatformMediaStreamSource* source) {
    std::move(source_ready)
        .Run(source, blink::mojom::blink::MediaStreamRequestResult::OK, "");
  }

  std::unique_ptr<WebMediaStreamDeviceObserver> media_stream_device_observer_;
  mojo::Remote<blink::mojom::blink::MediaDevicesDispatcherHost>
      media_devices_dispatcher_;
  MockMediaStreamVideoCapturerSource* video_source_ = nullptr;
  MockLocalMediaStreamAudioSource* local_audio_source_ = nullptr;
  bool create_source_that_fails_ = false;
  Member<MediaStreamDescriptor> last_generated_descriptor_;
  blink::mojom::blink::MediaStreamRequestResult result_ =
      blink::mojom::blink::MediaStreamRequestResult::NUM_MEDIA_REQUEST_RESULTS;
  String constraint_name_;
  RequestState* state_;
};

class UserMediaClientUnderTest : public UserMediaClient {
 public:
  UserMediaClientUnderTest(LocalFrame* frame,
                           UserMediaProcessor* user_media_processor,
                           RequestState* state)
      : UserMediaClient(
            frame,
            user_media_processor,
            blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
        state_(state) {}

  void RequestUserMediaForTest(UserMediaRequest* user_media_request) {
    *state_ = REQUEST_NOT_COMPLETE;
    RequestUserMedia(user_media_request);
    base::RunLoop().RunUntilIdle();
  }

  void RequestUserMediaForTest() {
    UserMediaRequest* user_media_request = UserMediaRequest::CreateForTesting(
        CreateDefaultConstraints(), CreateDefaultConstraints());
    RequestUserMediaForTest(user_media_request);
  }

 private:
  RequestState* state_;
};

class UserMediaChromeClient : public EmptyChromeClient {
 public:
  UserMediaChromeClient()
      : screen_info_({.rect = gfx::Rect(blink::kDefaultScreenCastWidth,
                                        blink::kDefaultScreenCastHeight)}) {}

  const ScreenInfo& GetScreenInfo(LocalFrame&) const override {
    return screen_info_;
  }

 private:
  const ScreenInfo screen_info_;
};

}  // namespace

class UserMediaClientTest : public ::testing::Test {
 public:
  UserMediaClientTest()
      : user_media_processor_receiver_(&media_devices_dispatcher_),
        user_media_client_receiver_(&media_devices_dispatcher_) {}

  void SetUp() override {
    // Create our test object.
    auto* msd_observer = new blink::WebMediaStreamDeviceObserver(nullptr);

    ChromeClient* client = MakeGarbageCollected<UserMediaChromeClient>();
    Page::PageClients page_clients;
    page_clients.chrome_client = client;
    dummy_page_holder_ =
        std::make_unique<DummyPageHolder>(IntSize(1, 1), &page_clients);

    user_media_processor_ = MakeGarbageCollected<UserMediaProcessorUnderTest>(
        &(dummy_page_holder_->GetFrame()), base::WrapUnique(msd_observer),
        user_media_processor_receiver_.BindNewPipeAndPassRemote(), &state_);
    user_media_processor_->set_media_stream_dispatcher_host_for_testing(
        mock_dispatcher_host_.CreatePendingRemoteAndBind());

    user_media_client_impl_ = MakeGarbageCollected<UserMediaClientUnderTest>(
        &(dummy_page_holder_->GetFrame()), user_media_processor_, &state_);

    user_media_client_impl_->SetMediaDevicesDispatcherForTesting(
        user_media_client_receiver_.BindNewPipeAndPassRemote());
  }

  void TearDown() override {
    user_media_client_impl_->ContextDestroyed();
    user_media_client_impl_ = nullptr;

    blink::WebHeap::CollectAllGarbageForTesting();
  }

  void LoadNewDocumentInFrame() {
    user_media_client_impl_->ContextDestroyed();
    base::RunLoop().RunUntilIdle();
  }

  MediaStreamDescriptor* RequestLocalMediaStream() {
    user_media_client_impl_->RequestUserMediaForTest();
    StartMockedVideoSource();

    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());

    MediaStreamDescriptor* desc =
        user_media_processor_->last_generated_descriptor();
    auto audio_components = desc->AudioComponents();
    auto video_components = desc->VideoComponents();

    EXPECT_EQ(1u, audio_components.size());
    EXPECT_EQ(1u, video_components.size());
    EXPECT_NE(audio_components[0]->Id(), video_components[0]->Id());
    return desc;
  }

  MediaStreamComponent* RequestLocalVideoTrack() {
    UserMediaRequest* user_media_request = UserMediaRequest::CreateForTesting(
        MediaConstraints(), CreateDefaultConstraints());
    user_media_client_impl_->RequestUserMediaForTest(user_media_request);
    StartMockedVideoSource();
    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());

    MediaStreamDescriptor* descriptor =
        user_media_processor_->last_generated_descriptor();
    auto audio_components = descriptor->AudioComponents();
    auto video_components = descriptor->VideoComponents();

    EXPECT_EQ(audio_components.size(), 0U);
    EXPECT_EQ(video_components.size(), 1U);

    return video_components[0];
  }

  MediaStreamComponent* RequestLocalAudioTrackWithAssociatedSink(
      bool render_to_associated_sink) {
    blink::MockConstraintFactory constraint_factory;
    constraint_factory.basic().render_to_associated_sink.SetExact(
        render_to_associated_sink);
    UserMediaRequest* user_media_request = UserMediaRequest::CreateForTesting(
        constraint_factory.CreateMediaConstraints(), MediaConstraints());
    user_media_client_impl_->RequestUserMediaForTest(user_media_request);

    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());

    MediaStreamDescriptor* desc =
        user_media_processor_->last_generated_descriptor();
    auto audio_components = desc->AudioComponents();
    auto video_components = desc->VideoComponents();

    EXPECT_EQ(audio_components.size(), 1u);
    EXPECT_TRUE(video_components.IsEmpty());

    return audio_components[0];
  }

  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 MediaConstraints& audio_constraints,
      const MediaConstraints& video_constraints,
      const std::string& expected_audio_device_id,
      const std::string& expected_video_device_id) {
    DCHECK(!audio_constraints.IsNull());
    DCHECK(!video_constraints.IsNull());
    UserMediaRequest* request = UserMediaRequest::CreateForTesting(
        audio_constraints, video_constraints);
    user_media_client_impl_->RequestUserMediaForTest(request);
    StartMockedVideoSource();

    EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
    EXPECT_EQ(1U, mock_dispatcher_host_.audio_devices().size());
    EXPECT_EQ(1U, mock_dispatcher_host_.video_devices().size());
    // MockMojoMediaStreamDispatcherHost appends its internal session ID to its
    // internal device IDs.
    EXPECT_EQ(std::string(expected_audio_device_id) +
                  mock_dispatcher_host_.session_id().ToString(),
              mock_dispatcher_host_.audio_devices()[0].id);
    EXPECT_EQ(std::string(expected_video_device_id) +
                  mock_dispatcher_host_.session_id().ToString(),
              mock_dispatcher_host_.video_devices()[0].id);
  }

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

    auto* apply_constraints_request =
        MakeGarbageCollected<ApplyConstraintsRequest>(
            component, factory.CreateMediaConstraints(), nullptr);
    user_media_client_impl_->ApplyConstraints(apply_constraints_request);
    base::RunLoop().RunUntilIdle();
  }

  RequestState request_state() const { return state_; }

 protected:
  ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport>
      testing_platform_;
  MockMojoMediaStreamDispatcherHost mock_dispatcher_host_;
  MockMediaDevicesDispatcherHost media_devices_dispatcher_;
  mojo::Receiver<blink::mojom::blink::MediaDevicesDispatcherHost>
      user_media_processor_receiver_;
  mojo::Receiver<blink::mojom::blink::MediaDevicesDispatcherHost>
      user_media_client_receiver_;

  std::unique_ptr<DummyPageHolder> dummy_page_holder_;
  WeakPersistent<UserMediaProcessorUnderTest> user_media_processor_;
  Persistent<UserMediaClientUnderTest> user_media_client_impl_;
  RequestState state_ = REQUEST_NOT_STARTED;
};

TEST_F(UserMediaClientTest, GenerateMediaStream) {
  // Generate a stream with both audio and video.
  MediaStreamDescriptor* mixed_desc = RequestLocalMediaStream();
  EXPECT_TRUE(mixed_desc);
}

// Test that the same source object is used if two MediaStreams are generated
// using the same source.
TEST_F(UserMediaClientTest, GenerateTwoMediaStreamsWithSameSource) {
  MediaStreamDescriptor* desc1 = RequestLocalMediaStream();
  MediaStreamDescriptor* desc2 = RequestLocalMediaStream();

  auto desc1_video_components = desc1->VideoComponents();
  auto desc2_video_components = desc2->VideoComponents();
  EXPECT_EQ(desc1_video_components[0]->Source()->Id(),
            desc2_video_components[0]->Source()->Id());

  EXPECT_EQ(desc1_video_components[0]->Source()->GetPlatformSource(),
            desc2_video_components[0]->Source()->GetPlatformSource());

  auto desc1_audio_components = desc1->AudioComponents();
  auto desc2_audio_components = desc2->AudioComponents();
  EXPECT_EQ(desc1_audio_components[0]->Source()->Id(),
            desc2_audio_components[0]->Source()->Id());

  EXPECT_EQ(MediaStreamAudioSource::From(desc1_audio_components[0]->Source()),
            MediaStreamAudioSource::From(desc2_audio_components[0]->Source()));
}

// Test that the same source object is not used if two MediaStreams are
// generated using different sources.
TEST_F(UserMediaClientTest, GenerateTwoMediaStreamsWithDifferentSources) {
  MediaStreamDescriptor* desc1 = RequestLocalMediaStream();
  // Make sure another device is selected (another |session_id|) in  the next
  // gUM request.
  mock_dispatcher_host_.ResetSessionId();
  MediaStreamDescriptor* desc2 = RequestLocalMediaStream();

  auto desc1_video_components = desc1->VideoComponents();
  auto desc2_video_components = desc2->VideoComponents();
  EXPECT_NE(desc1_video_components[0]->Source()->Id(),
            desc2_video_components[0]->Source()->Id());

  EXPECT_NE(desc1_video_components[0]->Source()->GetPlatformSource(),
            desc2_video_components[0]->Source()->GetPlatformSource());

  auto desc1_audio_components = desc1->AudioComponents();
  auto desc2_audio_components = desc2->AudioComponents();
  EXPECT_NE(desc1_audio_components[0]->Source()->Id(),
            desc2_audio_components[0]->Source()->Id());

  EXPECT_NE(MediaStreamAudioSource::From(desc1_audio_components[0]->Source()),
            MediaStreamAudioSource::From(desc2_audio_components[0]->Source()));
}

TEST_F(UserMediaClientTest, StopLocalTracks) {
  // Generate a stream with both audio and video.
  MediaStreamDescriptor* mixed_desc = RequestLocalMediaStream();

  auto audio_components = mixed_desc->AudioComponents();
  MediaStreamTrackPlatform* audio_track = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(audio_components[0]));
  audio_track->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());

  auto video_components = mixed_desc->VideoComponents();
  MediaStreamTrackPlatform* video_track = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(video_components[0]));
  video_track->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, mock_dispatcher_host_.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(UserMediaClientTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
  // Generate a stream with both audio and video.
  MediaStreamDescriptor* desc1 = RequestLocalMediaStream();
  MediaStreamDescriptor* desc2 = RequestLocalMediaStream();

  auto audio_components1 = desc1->AudioComponents();
  MediaStreamTrackPlatform* audio_track1 = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(audio_components1[0]));
  audio_track1->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, mock_dispatcher_host_.stop_audio_device_counter());

  auto audio_components2 = desc2->AudioComponents();
  MediaStreamTrackPlatform* audio_track2 = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(audio_components2[0]));
  audio_track2->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());

  auto video_components1 = desc1->VideoComponents();
  MediaStreamTrackPlatform* video_track1 = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(video_components1[0]));
  video_track1->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, mock_dispatcher_host_.stop_video_device_counter());

  auto video_components2 = desc2->VideoComponents();
  MediaStreamTrackPlatform* video_track2 = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(video_components2[0]));
  video_track2->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}

TEST_F(UserMediaClientTest, 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();
  base::RunLoop().RunUntilIdle();

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

// Test that the MediaStreams are deleted if a new document is loaded in the
// frame.
TEST_F(UserMediaClientTest, LoadNewDocumentInFrame) {
  // Test a stream with both audio and video.
  MediaStreamDescriptor* mixed_desc = RequestLocalMediaStream();
  EXPECT_TRUE(mixed_desc);
  MediaStreamDescriptor* desc2 = RequestLocalMediaStream();
  EXPECT_TRUE(desc2);
  LoadNewDocumentInFrame();
  WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}

// This test what happens if a video source to a MediaSteam fails to start.
TEST_F(UserMediaClientTest, MediaVideoSourceFailToStart) {
  user_media_client_impl_->RequestUserMediaForTest();
  FailToStartMockedVideoSource();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(REQUEST_FAILED, request_state());
  EXPECT_EQ(
      blink::mojom::blink::MediaStreamRequestResult::TRACK_START_FAILURE_VIDEO,
      user_media_processor_->error_reason());
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}

// This test what happens if an audio source fail to initialize.
TEST_F(UserMediaClientTest, MediaAudioSourceFailToInitialize) {
  user_media_processor_->SetCreateSourceThatFails(true);
  user_media_client_impl_->RequestUserMediaForTest();
  StartMockedVideoSource();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(REQUEST_FAILED, request_state());
  EXPECT_EQ(
      blink::mojom::blink::MediaStreamRequestResult::TRACK_START_FAILURE_AUDIO,
      user_media_processor_->error_reason());
  blink::WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}

// This test what happens if UserMediaClient is deleted before a source has
// started.
TEST_F(UserMediaClientTest, MediaStreamImplShutDown) {
  user_media_client_impl_->RequestUserMediaForTest();
  EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
  EXPECT_EQ(REQUEST_NOT_COMPLETE, request_state());
  // TearDown() nulls out |user_media_client_impl_| and forces GC to garbage
  // collect it.
}

// This test what happens if a new document is loaded in the frame while the
// MediaStream is being generated by the blink::WebMediaStreamDeviceObserver.
TEST_F(UserMediaClientTest, ReloadFrameWhileGeneratingStream) {
  mock_dispatcher_host_.DoNotRunCallback();

  user_media_client_impl_->RequestUserMediaForTest();
  LoadNewDocumentInFrame();
  EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
  EXPECT_EQ(0, mock_dispatcher_host_.stop_audio_device_counter());
  EXPECT_EQ(0, mock_dispatcher_host_.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(UserMediaClientTest, ReloadFrameWhileGeneratingSources) {
  user_media_client_impl_->RequestUserMediaForTest();
  EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
  LoadNewDocumentInFrame();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.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(UserMediaClientTest, StopTrackAfterReload) {
  MediaStreamDescriptor* mixed_desc = RequestLocalMediaStream();
  EXPECT_EQ(1, mock_dispatcher_host_.request_stream_counter());
  LoadNewDocumentInFrame();
  WebHeap::CollectAllGarbageForTesting();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
  EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());

  auto audio_components = mixed_desc->AudioComponents();
  MediaStreamTrackPlatform* audio_track = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(audio_components[0]));
  audio_track->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());

  auto video_components = mixed_desc->VideoComponents();
  MediaStreamTrackPlatform* video_track = MediaStreamTrackPlatform::GetTrack(
      WebMediaStreamTrack(video_components[0]));
  video_track->Stop();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, mock_dispatcher_host_.stop_video_device_counter());
}

TEST_F(UserMediaClientTest, DefaultConstraintsPropagate) {
  UserMediaRequest* request = UserMediaRequest::CreateForTesting(
      CreateDefaultConstraints(), CreateDefaultConstraints());
  user_media_client_impl_->RequestUserMediaForTest(request);
  blink::AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  blink::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_TRUE(audio_capture_settings.disable_local_echo());
  EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());

  const blink::AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_EQ(EchoCancellationType::kEchoCancellationAec3,
            properties.echo_cancellation_type);
  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(
      blink::AudioProcessingProperties().goog_experimental_echo_cancellation,
      properties.goog_experimental_echo_cancellation);
  EXPECT_TRUE(properties.goog_noise_suppression);
  EXPECT_TRUE(properties.goog_experimental_noise_suppression);
  EXPECT_TRUE(properties.goog_highpass_filter);
  EXPECT_TRUE(properties.goog_experimental_auto_gain_control);

  EXPECT_TRUE(video_capture_settings.HasValue());
  EXPECT_EQ(video_capture_settings.Width(),
            blink::MediaStreamVideoSource::kDefaultWidth);
  EXPECT_EQ(video_capture_settings.Height(),
            blink::MediaStreamVideoSource::kDefaultHeight);
  EXPECT_EQ(
      video_capture_settings.FrameRate(),
      static_cast<float>(blink::MediaStreamVideoSource::kDefaultFrameRate));
  EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
            media::ResolutionChangePolicy::FIXED_RESOLUTION);
  EXPECT_FALSE(video_capture_settings.noise_reduction());
  EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());

  const blink::VideoTrackAdapterSettings& track_settings =
      video_capture_settings.track_adapter_settings();
  EXPECT_FALSE(track_settings.target_size().has_value());
  EXPECT_EQ(
      track_settings.min_aspect_ratio(),
      1.0 / static_cast<double>(blink::MediaStreamVideoSource::kDefaultHeight));
  EXPECT_EQ(track_settings.max_aspect_ratio(),
            static_cast<double>(blink::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(UserMediaClientTest, DefaultTabCapturePropagate) {
  blink::MockConstraintFactory factory;
  factory.basic().media_stream_source.SetExact(kMediaStreamSourceTab);
  MediaConstraints audio_constraints = factory.CreateMediaConstraints();
  MediaConstraints video_constraints = factory.CreateMediaConstraints();
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  blink::AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  blink::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_TRUE(audio_capture_settings.disable_local_echo());
  EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());

  const blink::AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
            properties.echo_cancellation_type);
  EXPECT_FALSE(properties.goog_audio_mirroring);
  EXPECT_FALSE(properties.goog_auto_gain_control);
  EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
  EXPECT_FALSE(properties.goog_noise_suppression);
  EXPECT_FALSE(properties.goog_experimental_noise_suppression);
  EXPECT_FALSE(properties.goog_highpass_filter);
  EXPECT_FALSE(properties.goog_experimental_auto_gain_control);

  EXPECT_TRUE(video_capture_settings.HasValue());
  EXPECT_EQ(video_capture_settings.Width(), blink::kDefaultScreenCastWidth);
  EXPECT_EQ(video_capture_settings.Height(), blink::kDefaultScreenCastHeight);
  EXPECT_EQ(video_capture_settings.FrameRate(),
            blink::kDefaultScreenCastFrameRate);
  EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
            media::ResolutionChangePolicy::FIXED_RESOLUTION);
  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 blink::VideoTrackAdapterSettings& track_settings =
      video_capture_settings.track_adapter_settings();
  EXPECT_EQ(track_settings.target_width(), blink::kDefaultScreenCastWidth);
  EXPECT_EQ(track_settings.target_height(), blink::kDefaultScreenCastHeight);
  EXPECT_EQ(track_settings.min_aspect_ratio(),
            1.0 / blink::kMaxScreenCastDimension);
  EXPECT_EQ(track_settings.max_aspect_ratio(), blink::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(UserMediaClientTest, DefaultDesktopCapturePropagate) {
  blink::MockConstraintFactory factory;
  factory.basic().media_stream_source.SetExact(kMediaStreamSourceDesktop);
  MediaConstraints audio_constraints = factory.CreateMediaConstraints();
  MediaConstraints video_constraints = factory.CreateMediaConstraints();
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  blink::AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  blink::VideoCaptureSettings video_capture_settings =
      user_media_processor_->VideoSettings();
  user_media_client_impl_->CancelUserMediaRequest(request);
  base::RunLoop().RunUntilIdle();

  // 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.disable_local_echo());
  EXPECT_FALSE(audio_capture_settings.render_to_associated_sink());

  const blink::AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
            properties.echo_cancellation_type);
  EXPECT_FALSE(properties.goog_audio_mirroring);
  EXPECT_FALSE(properties.goog_auto_gain_control);
  EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
  EXPECT_FALSE(properties.goog_noise_suppression);
  EXPECT_FALSE(properties.goog_experimental_noise_suppression);
  EXPECT_FALSE(properties.goog_highpass_filter);
  EXPECT_FALSE(properties.goog_experimental_auto_gain_control);

  EXPECT_TRUE(video_capture_settings.HasValue());
  EXPECT_EQ(video_capture_settings.Width(), blink::kDefaultScreenCastWidth);
  EXPECT_EQ(video_capture_settings.Height(), blink::kDefaultScreenCastHeight);
  EXPECT_EQ(video_capture_settings.FrameRate(),
            blink::kDefaultScreenCastFrameRate);
  EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
            media::ResolutionChangePolicy::ANY_WITHIN_LIMIT);
  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 blink::VideoTrackAdapterSettings& track_settings =
      video_capture_settings.track_adapter_settings();
  EXPECT_EQ(track_settings.target_width(), blink::kDefaultScreenCastWidth);
  EXPECT_EQ(track_settings.target_height(), blink::kDefaultScreenCastHeight);
  EXPECT_EQ(track_settings.min_aspect_ratio(),
            1.0 / blink::kMaxScreenCastDimension);
  EXPECT_EQ(track_settings.max_aspect_ratio(), blink::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(UserMediaClientTest, NonDefaultAudioConstraintsPropagate) {
  mock_dispatcher_host_.DoNotRunCallback();

  blink::MockConstraintFactory factory;
  factory.basic().device_id.SetExact(kFakeAudioInputDeviceId1);
  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);
  MediaConstraints audio_constraints = factory.CreateMediaConstraints();
  // Request contains only audio
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(audio_constraints, MediaConstraints());
  user_media_client_impl_->RequestUserMediaForTest(request);
  blink::AudioCaptureSettings audio_capture_settings =
      user_media_processor_->AudioSettings();
  blink::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.disable_local_echo());
  EXPECT_TRUE(audio_capture_settings.render_to_associated_sink());

  const blink::AudioProcessingProperties& properties =
      audio_capture_settings.audio_processing_properties();
  EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
            properties.echo_cancellation_type);
  EXPECT_TRUE(properties.goog_audio_mirroring);
  EXPECT_FALSE(properties.goog_auto_gain_control);
  EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
  EXPECT_FALSE(properties.goog_noise_suppression);
  EXPECT_FALSE(properties.goog_experimental_noise_suppression);
  EXPECT_FALSE(properties.goog_highpass_filter);
  EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
}

TEST_F(UserMediaClientTest, CreateWithMandatoryInvalidAudioDeviceId) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(kInvalidDeviceId);
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(audio_constraints, MediaConstraints());
  user_media_client_impl_->RequestUserMediaForTest(request);
  EXPECT_EQ(REQUEST_FAILED, request_state());
}

TEST_F(UserMediaClientTest, CreateWithMandatoryInvalidVideoDeviceId) {
  MediaConstraints video_constraints =
      CreateDeviceConstraints(kInvalidDeviceId);
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(MediaConstraints(), video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  EXPECT_EQ(REQUEST_FAILED, request_state());
}

TEST_F(UserMediaClientTest, CreateWithMandatoryValidDeviceIds) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(kFakeAudioInputDeviceId1);
  MediaConstraints video_constraints =
      CreateDeviceConstraints(kFakeVideoInputDeviceId1);
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientTest, CreateWithBasicIdealValidDeviceId) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(nullptr, kFakeAudioInputDeviceId1);
  MediaConstraints video_constraints =
      CreateDeviceConstraints(nullptr, kFakeVideoInputDeviceId1);
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientTest, CreateWithAdvancedExactValidDeviceId) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(nullptr, nullptr, kFakeAudioInputDeviceId1);
  MediaConstraints video_constraints =
      CreateDeviceConstraints(nullptr, nullptr, kFakeVideoInputDeviceId1);
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientTest, CreateWithAllOptionalInvalidDeviceId) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
  MediaConstraints video_constraints =
      CreateDeviceConstraints(nullptr, kInvalidDeviceId, kInvalidDeviceId);
  // MockMojoMediaStreamDispatcherHost 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(UserMediaClientTest, CreateWithFacingModeUser) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(kFakeAudioInputDeviceId1);
  MediaConstraints video_constraints = CreateFacingModeConstraints("user");
  // kFakeVideoInputDeviceId1 has user facing mode.
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId1);
}

TEST_F(UserMediaClientTest, CreateWithFacingModeEnvironment) {
  MediaConstraints audio_constraints =
      CreateDeviceConstraints(kFakeAudioInputDeviceId1);
  MediaConstraints video_constraints =
      CreateFacingModeConstraints("environment");
  // kFakeVideoInputDeviceId2 has environment facing mode.
  TestValidRequestWithConstraints(audio_constraints, video_constraints,
                                  kFakeAudioInputDeviceId1,
                                  kFakeVideoInputDeviceId2);
}

TEST_F(UserMediaClientTest, ApplyConstraintsVideoDeviceSingleTrack) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component = RequestLocalVideoTrack();
  MediaStreamVideoTrack* track = MediaStreamVideoTrack::From(component);
  blink::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(component, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 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(component, 801, 600);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 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(component, 800, 600);
  CheckVideoSourceAndTrack(source, 800, 600, 30.0, component, 800, 600, 30.0);

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

TEST_F(UserMediaClientTest, ApplyConstraintsVideoDeviceTwoTracks) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component = 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(component, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 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_, OnStreamStarted(_));
  MediaStreamComponent* component2 = RequestLocalVideoTrack();
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component2, 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(component, 800, 600);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 800, 600, 20.0);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component2, 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.
  // https://crbug.com/768205.
  ApplyConstraintsVideoMode(component, 800, 600, 30.0);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 800, 600, 20.0);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component2, 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.
  blink::MediaStreamTrackPlatform::GetTrack(WebMediaStreamTrack(component2))
      ->Stop();
  ApplyConstraintsVideoMode(component, 800, 600, 30.0);
  CheckVideoSourceAndTrack(source, 800, 600, 30.0, component, 800, 600, 30.0);
}

TEST_F(UserMediaClientTest, ApplyConstraintsVideoDeviceFailsToStopForRestart) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component = 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(component, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 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(component, 640, 480);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 640, 480, 20.0);
}

TEST_F(UserMediaClientTest,
       ApplyConstraintsVideoDeviceFailsToRestartAfterStop) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component = 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(component, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 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(component, 640, 480);

  EXPECT_EQ(component->Source()->GetReadyState(),
            MediaStreamSource::kReadyStateEnded);
  EXPECT_FALSE(source->IsRunning());
}

TEST_F(UserMediaClientTest, ApplyConstraintsVideoDeviceStopped) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component = 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(component, 1024, 768);
  CheckVideoSourceAndTrack(source, 1024, 768, 20.0, component, 1024, 768, 20.0);

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

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

// These tests check that the associated output device id is
// set according to the renderToAssociatedSink constrainable property.
TEST_F(UserMediaClientTest,
       RenderToAssociatedSinkTrueAssociatedOutputDeviceId) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component =
      RequestLocalAudioTrackWithAssociatedSink(true);
  MediaStreamAudioSource* source =
      MediaStreamAudioSource::From(component->Source());
  EXPECT_TRUE(source->device().matched_output_device_id);
}

TEST_F(UserMediaClientTest,
       RenderToAssociatedSinkFalseAssociatedOutputDeviceId) {
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamComponent* component =
      RequestLocalAudioTrackWithAssociatedSink(false);
  MediaStreamAudioSource* source =
      MediaStreamAudioSource::From(component->Source());
  EXPECT_FALSE(source->device().matched_output_device_id);
}

TEST_F(UserMediaClientTest, IsCapturing) {
  EXPECT_FALSE(user_media_client_impl_->IsCapturing());
  EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
  MediaStreamDescriptor* descriptor = RequestLocalMediaStream();
  EXPECT_TRUE(user_media_client_impl_->IsCapturing());

  user_media_client_impl_->StopTrack(descriptor->AudioComponents()[0]);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(user_media_client_impl_->IsCapturing());

  user_media_client_impl_->StopTrack(descriptor->VideoComponents()[0]);
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(user_media_client_impl_->IsCapturing());
}

TEST_F(UserMediaClientTest, DesktopCaptureChangeSource) {
  blink::MockConstraintFactory factory;
  factory.basic().media_stream_source.SetExact(
      blink::WebString::FromASCII(blink::kMediaStreamSourceDesktop));
  MediaConstraints audio_constraints = factory.CreateMediaConstraints();
  MediaConstraints video_constraints = factory.CreateMediaConstraints();
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);

  // Test changing video source.
  MockMediaStreamVideoCapturerSource* video_source =
      user_media_processor_->last_created_video_source();
  blink::MediaStreamDevice fake_video_device(
      blink::mojom::blink::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE,
      kFakeVideoInputDeviceId1, "Fake Video Device");
  EXPECT_CALL(*video_source, ChangeSourceImpl(_));
  user_media_processor_->OnDeviceChanged(video_source->device(),
                                         fake_video_device);

  // Test changing audio source.
  MockLocalMediaStreamAudioSource* audio_source =
      user_media_processor_->last_created_local_audio_source();
  EXPECT_NE(audio_source, nullptr);
  blink::MediaStreamDevice fake_audio_device(
      blink::mojom::blink::MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE,
      kFakeVideoInputDeviceId1, "Fake Audio Device");
  EXPECT_CALL(*audio_source, EnsureSourceIsStopped()).Times(2);
  user_media_processor_->OnDeviceChanged(audio_source->device(),
                                         fake_audio_device);

  user_media_client_impl_->CancelUserMediaRequest(request);
  base::RunLoop().RunUntilIdle();
}

TEST_F(UserMediaClientTest, DesktopCaptureChangeSourceWithoutAudio) {
  blink::MockConstraintFactory factory;
  factory.basic().media_stream_source.SetExact(kMediaStreamSourceDesktop);
  MediaConstraints audio_constraints = factory.CreateMediaConstraints();
  MediaConstraints video_constraints = factory.CreateMediaConstraints();
  UserMediaRequest* request =
      UserMediaRequest::CreateForTesting(audio_constraints, video_constraints);
  user_media_client_impl_->RequestUserMediaForTest(request);
  EXPECT_EQ(1U, mock_dispatcher_host_.audio_devices().size());
  EXPECT_EQ(1U, mock_dispatcher_host_.video_devices().size());

  // If the new desktop capture source doesn't have audio, the previous audio
  // device should be stopped. Here |EnsureSourceIsStopped()| should be called
  // only once by |OnDeviceChanged()|.
  MockLocalMediaStreamAudioSource* audio_source =
      user_media_processor_->last_created_local_audio_source();
  EXPECT_NE(audio_source, nullptr);
  EXPECT_CALL(*audio_source, EnsureSourceIsStopped()).Times(1);
  blink::MediaStreamDevice fake_audio_device(
      blink::mojom::blink::MediaStreamType::NO_SERVICE, "", "");
  user_media_processor_->OnDeviceChanged(audio_source->device(),
                                         fake_audio_device);
  base::RunLoop().RunUntilIdle();

  Mock::VerifyAndClearExpectations(audio_source);
  EXPECT_CALL(*audio_source, EnsureSourceIsStopped()).Times(0);
  user_media_client_impl_->CancelUserMediaRequest(request);
  base::RunLoop().RunUntilIdle();
}

TEST_F(UserMediaClientTest, PanConstraintRequestPanTiltZoomPermission) {
  EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      CreateDefaultConstraints()));

  blink::MockConstraintFactory basic_factory;
  basic_factory.basic().pan.SetIsPresent(true);
  EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      basic_factory.CreateMediaConstraints()));

  blink::MockConstraintFactory advanced_factory;
  auto& exact_advanced = advanced_factory.AddAdvanced();
  exact_advanced.pan.SetIsPresent(true);
  EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      advanced_factory.CreateMediaConstraints()));
}

TEST_F(UserMediaClientTest, TiltConstraintRequestPanTiltZoomPermission) {
  EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      CreateDefaultConstraints()));

  blink::MockConstraintFactory basic_factory;
  basic_factory.basic().tilt.SetIsPresent(true);
  EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      basic_factory.CreateMediaConstraints()));

  blink::MockConstraintFactory advanced_factory;
  auto& exact_advanced = advanced_factory.AddAdvanced();
  exact_advanced.tilt.SetIsPresent(true);
  EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      advanced_factory.CreateMediaConstraints()));
}

TEST_F(UserMediaClientTest, ZoomConstraintRequestPanTiltZoomPermission) {
  EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      CreateDefaultConstraints()));

  blink::MockConstraintFactory basic_factory;
  basic_factory.basic().zoom.SetIsPresent(true);
  EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      basic_factory.CreateMediaConstraints()));

  blink::MockConstraintFactory advanced_factory;
  auto& exact_advanced = advanced_factory.AddAdvanced();
  exact_advanced.zoom.SetIsPresent(true);
  EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested(
      advanced_factory.CreateMediaConstraints()));
}

}  // namespace blink
