// Copyright 2014 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/media_stream_video_capturer_source.h"

#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "content/child/child_process.h"
#include "content/public/renderer/media_stream_video_sink.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/mock_constraint_factory.h"
#include "media/base/bind_to_current_loop.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/web/WebHeap.h"

using ::testing::_;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::WithArgs;

namespace content {

class MockVideoCapturerSource : public media::VideoCapturerSource {
 public:
  MockVideoCapturerSource() {
    ON_CALL(*this, GetCurrentSupportedFormats(_, _, _, _))
        .WillByDefault(WithArgs<3>(
            Invoke(this, &MockVideoCapturerSource::EnumerateDeviceFormats)));
  }

  MOCK_METHOD0(RequestRefreshFrame, void());
  MOCK_METHOD4(GetCurrentSupportedFormats,
              void(int max_requested_width,
                   int max_requested_height,
                   double max_requested_frame_rate,
                   const VideoCaptureDeviceFormatsCB& callback));
  MOCK_METHOD3(StartCapture,
               void(const media::VideoCaptureParams& params,
                    const VideoCaptureDeliverFrameCB& new_frame_callback,
                    const RunningCallback& running_callback));
  MOCK_METHOD0(StopCapture, void());

  void EnumerateDeviceFormats(const VideoCaptureDeviceFormatsCB& callback) {
    media::VideoCaptureFormat kFormatSmall(gfx::Size(640, 480), 30.0,
                                           media::PIXEL_FORMAT_I420);
    media::VideoCaptureFormat kFormatLarge(gfx::Size(1920, 1080), 30.0,
                                           media::PIXEL_FORMAT_I420);
    media::VideoCaptureFormats formats;
    formats.push_back(kFormatSmall);
    formats.push_back(kFormatLarge);
    callback.Run(formats);
  }
};

class MediaStreamVideoCapturerSourceTest : public testing::Test {
 public:
  MediaStreamVideoCapturerSourceTest()
      : child_process_(new ChildProcess()),
        source_(nullptr),
        delegate_(nullptr),
        source_stopped_(false) {}

  void TearDown() override {
    webkit_source_.reset();
    blink::WebHeap::collectAllGarbageForTesting();
  }

  void InitWithDeviceInfo(const StreamDeviceInfo& device_info) {
    std::unique_ptr<MockVideoCapturerSource> delegate(
        new MockVideoCapturerSource());
    delegate_ = delegate.get();
    source_ = new MediaStreamVideoCapturerSource(
        base::Bind(&MediaStreamVideoCapturerSourceTest::OnSourceStopped,
                   base::Unretained(this)),
        std::move(delegate));
    source_->SetDeviceInfo(device_info);

    webkit_source_.initialize(blink::WebString::fromASCII("dummy_source_id"),
                              blink::WebMediaStreamSource::TypeVideo,
                              blink::WebString::fromASCII("dummy_source_name"),
                              false /* remote */);
    webkit_source_.setExtraData(source_);
    webkit_source_id_ = webkit_source_.id();
  }

  MockConstraintFactory* constraint_factory() { return &constraint_factory_; }

  blink::WebMediaStreamTrack StartSource() {
    bool enabled = true;
    // CreateVideoTrack will trigger OnConstraintsApplied.
    return MediaStreamVideoTrack::CreateVideoTrack(
        source_, constraint_factory_.CreateWebMediaConstraints(),
        base::Bind(&MediaStreamVideoCapturerSourceTest::OnConstraintsApplied,
                   base::Unretained(this)),
        enabled);
  }

  MockVideoCapturerSource& mock_delegate() { return *delegate_; }

  const char* GetPowerLineFrequencyForTesting() const {
    return source_->GetPowerLineFrequencyForTesting();
  }

  void OnSourceStopped(const blink::WebMediaStreamSource& source) {
    source_stopped_ = true;
    EXPECT_EQ(source.id(), webkit_source_id_);
  }
  void OnStarted(bool result) { source_->OnRunStateChanged(result); }

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

  // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
  // and Sources below into believing they are on the right threads.
  base::MessageLoopForUI message_loop_;
  std::unique_ptr<ChildProcess> child_process_;

  blink::WebMediaStreamSource webkit_source_;
  MediaStreamVideoCapturerSource* source_;  // owned by |webkit_source_|.
  MockVideoCapturerSource* delegate_;     // owned by |source|.
  blink::WebString webkit_source_id_;
  bool source_stopped_;
  MockConstraintFactory constraint_factory_;
};

TEST_F(MediaStreamVideoCapturerSourceTest, TabCaptureFixedResolutionByDefault) {
  StreamDeviceInfo device_info;
  device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
  InitWithDeviceInfo(device_info);

  // No constraints are being provided to the implementation, so expect only
  // default values.
  media::VideoCaptureParams expected_params;
  expected_params.requested_format.frame_size.SetSize(
      MediaStreamVideoSource::kDefaultWidth,
      MediaStreamVideoSource::kDefaultHeight);
  expected_params.requested_format.frame_rate =
      MediaStreamVideoSource::kDefaultFrameRate;
  expected_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
  expected_params.resolution_change_policy =
      media::RESOLUTION_POLICY_FIXED_RESOLUTION;

  InSequence s;
  EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
  EXPECT_CALL(mock_delegate(), StartCapture(expected_params, _, _));
  blink::WebMediaStreamTrack track = StartSource();
  // When the track goes out of scope, the source will be stopped.
  EXPECT_CALL(mock_delegate(), StopCapture());
}

TEST_F(MediaStreamVideoCapturerSourceTest,
       DesktopCaptureAllowAnyResolutionChangeByDefault) {
  StreamDeviceInfo device_info;
  device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
  InitWithDeviceInfo(device_info);

  // No constraints are being provided to the implementation, so expect only
  // default values.
  media::VideoCaptureParams expected_params;
  expected_params.requested_format.frame_size.SetSize(
      MediaStreamVideoSource::kDefaultWidth,
      MediaStreamVideoSource::kDefaultHeight);
  expected_params.requested_format.frame_rate =
      MediaStreamVideoSource::kDefaultFrameRate;
  expected_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
  expected_params.resolution_change_policy =
      media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT;

  InSequence s;
  EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
  EXPECT_CALL(mock_delegate(), StartCapture(expected_params, _, _));
  blink::WebMediaStreamTrack track = StartSource();
  // When the track goes out of scope, the source will be stopped.
  EXPECT_CALL(mock_delegate(), StopCapture());
}

TEST_F(MediaStreamVideoCapturerSourceTest,
       TabCaptureConstraintsImplyFixedAspectRatio) {
  StreamDeviceInfo device_info;
  device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
  InitWithDeviceInfo(device_info);

  // Specify max and min size constraints that have the same ~16:9 aspect ratio.
  constraint_factory()->basic().width.setMax(1920);
  constraint_factory()->basic().height.setMax(1080);
  constraint_factory()->basic().width.setMin(854);
  constraint_factory()->basic().height.setMin(480);
  constraint_factory()->basic().frameRate.setMax(60.0);

  media::VideoCaptureParams expected_params;
  expected_params.requested_format.frame_size.SetSize(1920, 1080);
  expected_params.requested_format.frame_rate = 60.0;
  expected_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
  expected_params.resolution_change_policy =
      media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO;

  InSequence s;
  EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
  EXPECT_CALL(
      mock_delegate(),
      StartCapture(
          testing::Field(&media::VideoCaptureParams::resolution_change_policy,
                         media::RESOLUTION_POLICY_FIXED_ASPECT_RATIO),
          _, _));
  blink::WebMediaStreamTrack track = StartSource();
  // When the track goes out of scope, the source will be stopped.
  EXPECT_CALL(mock_delegate(), StopCapture());
}

TEST_F(MediaStreamVideoCapturerSourceTest,
       TabCaptureConstraintsImplyAllowingAnyResolutionChange) {
  StreamDeviceInfo device_info;
  device_info.device.type = MEDIA_TAB_VIDEO_CAPTURE;
  InitWithDeviceInfo(device_info);

  // Specify max and min size constraints with different aspect ratios.
  constraint_factory()->basic().width.setMax(1920);
  constraint_factory()->basic().height.setMax(1080);
  constraint_factory()->basic().width.setMin(0);
  constraint_factory()->basic().height.setMin(0);
  constraint_factory()->basic().frameRate.setMax(60.0);

  media::VideoCaptureParams expected_params;
  expected_params.requested_format.frame_size.SetSize(1920, 1080);
  expected_params.requested_format.frame_rate = 60.0;
  expected_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
  expected_params.resolution_change_policy =
      media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT;

  InSequence s;
  EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
  EXPECT_CALL(
      mock_delegate(),
      StartCapture(
          testing::Field(&media::VideoCaptureParams::resolution_change_policy,
                         media::RESOLUTION_POLICY_ANY_WITHIN_LIMIT),
          _, _));
  blink::WebMediaStreamTrack track = StartSource();
  // When the track goes out of scope, the source will be stopped.
  EXPECT_CALL(mock_delegate(), StopCapture());
}

TEST_F(MediaStreamVideoCapturerSourceTest,
       DeviceCaptureConstraintsSupportPowerLineFrequency) {
  for (int frequency = -100; frequency < 100; ++frequency) {
    StreamDeviceInfo device_info;
    device_info.device.type = MEDIA_DEVICE_VIDEO_CAPTURE;
    InitWithDeviceInfo(device_info);
    constraint_factory_.Reset();

    constraint_factory()->AddAdvanced().googPowerLineFrequency.setExact(
        frequency);

    media::VideoCaptureParams expected_params;
    expected_params.requested_format.frame_size.SetSize(
        MediaStreamVideoSource::kDefaultWidth,
        MediaStreamVideoSource::kDefaultHeight);
    expected_params.requested_format.frame_rate =
        MediaStreamVideoSource::kDefaultFrameRate;
    expected_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
    expected_params.resolution_change_policy =
        media::RESOLUTION_POLICY_FIXED_RESOLUTION;
    if (frequency == 50) {
      expected_params.power_line_frequency =
          media::PowerLineFrequency::FREQUENCY_50HZ;
    } else if (frequency == 60) {
      expected_params.power_line_frequency =
          media::PowerLineFrequency::FREQUENCY_60HZ;
    } else {
      expected_params.power_line_frequency =
          media::PowerLineFrequency::FREQUENCY_DEFAULT;
    }

    InSequence s;
    EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
    EXPECT_CALL(mock_delegate(), StartCapture(expected_params, _, _));
    blink::WebMediaStreamTrack track = StartSource();
    // When the track goes out of scope, the source will be stopped.
    EXPECT_CALL(mock_delegate(), StopCapture());
  }
}

TEST_F(MediaStreamVideoCapturerSourceTest, Ended) {
  std::unique_ptr<MockVideoCapturerSource> delegate(
      new MockVideoCapturerSource());
  delegate_ = delegate.get();
  source_ = new MediaStreamVideoCapturerSource(
      base::Bind(&MediaStreamVideoCapturerSourceTest::OnSourceStopped,
                 base::Unretained(this)),
      std::move(delegate));
  webkit_source_.initialize(blink::WebString::fromASCII("dummy_source_id"),
                            blink::WebMediaStreamSource::TypeVideo,
                            blink::WebString::fromASCII("dummy_source_name"),
                            false /* remote */);
  webkit_source_.setExtraData(source_);
  webkit_source_id_ = webkit_source_.id();

  InSequence s;
  EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
  EXPECT_CALL(mock_delegate(), StartCapture(_, _, _));
  blink::WebMediaStreamTrack track = StartSource();
  base::RunLoop().RunUntilIdle();

  OnStarted(true);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
            webkit_source_.getReadyState());

  EXPECT_FALSE(source_stopped_);

  EXPECT_CALL(mock_delegate(), StopCapture());
  OnStarted(false);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
            webkit_source_.getReadyState());
  // Verify that MediaStreamSource::SourceStoppedCallback has been triggered.
  EXPECT_TRUE(source_stopped_);
}

class FakeMediaStreamVideoSink : public MediaStreamVideoSink {
 public:
  FakeMediaStreamVideoSink(base::TimeTicks* capture_time,
                           media::VideoFrameMetadata* metadata,
                           base::Closure got_frame_cb)
      : capture_time_(capture_time),
        metadata_(metadata),
        got_frame_cb_(got_frame_cb) {}

  void ConnectToTrack(const blink::WebMediaStreamTrack& track) {
    MediaStreamVideoSink::ConnectToTrack(
        track, base::Bind(&FakeMediaStreamVideoSink::OnVideoFrame,
                          base::Unretained(this)),
        true);
  }

  void DisconnectFromTrack() {
    MediaStreamVideoSink::DisconnectFromTrack();
  }

  void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
                    base::TimeTicks capture_time) {
    *capture_time_ = capture_time;
    metadata_->Clear();
    metadata_->MergeMetadataFrom(frame->metadata());
    base::ResetAndReturn(&got_frame_cb_).Run();
  }

 private:
  base::TimeTicks* const capture_time_;
  media::VideoFrameMetadata* const metadata_;
  base::Closure got_frame_cb_;
};

TEST_F(MediaStreamVideoCapturerSourceTest, CaptureTimeAndMetadataPlumbing) {
  StreamDeviceInfo device_info;
  device_info.device.type = MEDIA_DESKTOP_VIDEO_CAPTURE;
  InitWithDeviceInfo(device_info);

  VideoCaptureDeliverFrameCB deliver_frame_cb;
  media::VideoCapturerSource::RunningCallback running_cb;

  InSequence s;
  EXPECT_CALL(mock_delegate(), GetCurrentSupportedFormats(_, _, _, _));
  EXPECT_CALL(mock_delegate(), StartCapture(_, _, _))
      .WillOnce(testing::DoAll(testing::SaveArg<1>(&deliver_frame_cb),
                               testing::SaveArg<2>(&running_cb)));
  EXPECT_CALL(mock_delegate(), RequestRefreshFrame());
  EXPECT_CALL(mock_delegate(), StopCapture());
  blink::WebMediaStreamTrack track = StartSource();
  running_cb.Run(true);

  base::RunLoop run_loop;
  base::TimeTicks reference_capture_time =
      base::TimeTicks::FromInternalValue(60013);
  base::TimeTicks capture_time;
  media::VideoFrameMetadata metadata;
  FakeMediaStreamVideoSink fake_sink(
      &capture_time, &metadata,
      media::BindToCurrentLoop(run_loop.QuitClosure()));
  fake_sink.ConnectToTrack(track);
  const scoped_refptr<media::VideoFrame> frame =
      media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2));
  frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, 30.0);
  child_process_->io_task_runner()->PostTask(
      FROM_HERE, base::Bind(deliver_frame_cb, frame, reference_capture_time));
  run_loop.Run();
  fake_sink.DisconnectFromTrack();
  EXPECT_EQ(reference_capture_time, capture_time);
  double metadata_value;
  EXPECT_TRUE(metadata.GetDouble(media::VideoFrameMetadata::FRAME_RATE,
                                 &metadata_value));
  EXPECT_EQ(30.0, metadata_value);
}

}  // namespace content
