diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-20 13:40:20 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-22 12:41:23 +0000 |
commit | 7961cea6d1041e3e454dae6a1da660b453efd238 (patch) | |
tree | c0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc | |
parent | b7034d0803538058e5c9d904ef03cf5eab34f6ef (diff) | |
download | qtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz |
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc new file mode 100644 index 00000000000..7a99f544a53 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/video_capture/video_capture_impl_test.cc @@ -0,0 +1,526 @@ +// 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 <stddef.h> +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/memory/read_only_shared_memory_region.h" +#include "base/memory/unsafe_shared_memory_region.h" +#include "base/test/task_environment.h" +#include "media/capture/mojom/video_capture.mojom-blink.h" +#include "media/capture/mojom/video_capture_types.mojom-blink.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/blink/renderer/platform/video_capture/video_capture_impl.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +using ::testing::_; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::SaveArg; +using ::testing::WithArgs; + +namespace blink { + +void RunEmptyFormatsCallback( + media::mojom::blink::VideoCaptureHost::GetDeviceSupportedFormatsCallback& + callback) { + Vector<media::VideoCaptureFormat> formats; + std::move(callback).Run(formats); +} + +ACTION(DoNothing) {} + +// Mock implementation of the Mojo Host service. +class MockMojoVideoCaptureHost : public media::mojom::blink::VideoCaptureHost { + public: + MockMojoVideoCaptureHost() : released_buffer_count_(0) { + ON_CALL(*this, GetDeviceSupportedFormatsMock(_, _, _)) + .WillByDefault(WithArgs<2>(Invoke(RunEmptyFormatsCallback))); + ON_CALL(*this, GetDeviceFormatsInUseMock(_, _, _)) + .WillByDefault(WithArgs<2>(Invoke(RunEmptyFormatsCallback))); + ON_CALL(*this, ReleaseBuffer(_, _, _)) + .WillByDefault(InvokeWithoutArgs( + this, &MockMojoVideoCaptureHost::increase_released_buffer_count)); + } + + // Start() can't be mocked directly due to move-only |observer|. + void Start(const base::UnguessableToken& device_id, + const base::UnguessableToken& session_id, + const media::VideoCaptureParams& params, + media::mojom::blink::VideoCaptureObserverPtr observer) override { + DoStart(device_id, session_id, params); + } + MOCK_METHOD3(DoStart, + void(const base::UnguessableToken&, + const base::UnguessableToken&, + const media::VideoCaptureParams&)); + MOCK_METHOD1(Stop, void(const base::UnguessableToken&)); + MOCK_METHOD1(Pause, void(const base::UnguessableToken&)); + MOCK_METHOD3(Resume, + void(const base::UnguessableToken&, + const base::UnguessableToken&, + const media::VideoCaptureParams&)); + MOCK_METHOD1(RequestRefreshFrame, void(const base::UnguessableToken&)); + MOCK_METHOD3(ReleaseBuffer, + void(const base::UnguessableToken&, int32_t, double)); + MOCK_METHOD3(GetDeviceSupportedFormatsMock, + void(const base::UnguessableToken&, + const base::UnguessableToken&, + GetDeviceSupportedFormatsCallback&)); + MOCK_METHOD3(GetDeviceFormatsInUseMock, + void(const base::UnguessableToken&, + const base::UnguessableToken&, + GetDeviceFormatsInUseCallback&)); + MOCK_METHOD2(OnFrameDropped, + void(const base::UnguessableToken&, + media::VideoCaptureFrameDropReason)); + MOCK_METHOD2(OnLog, void(const base::UnguessableToken&, const String&)); + + void GetDeviceSupportedFormats( + const base::UnguessableToken& arg1, + const base::UnguessableToken& arg2, + GetDeviceSupportedFormatsCallback arg3) override { + GetDeviceSupportedFormatsMock(arg1, arg2, arg3); + } + + void GetDeviceFormatsInUse(const base::UnguessableToken& arg1, + const base::UnguessableToken& arg2, + GetDeviceFormatsInUseCallback arg3) override { + GetDeviceFormatsInUseMock(arg1, arg2, arg3); + } + + int released_buffer_count() const { return released_buffer_count_; } + void increase_released_buffer_count() { released_buffer_count_++; } + + private: + int released_buffer_count_; + + DISALLOW_COPY_AND_ASSIGN(MockMojoVideoCaptureHost); +}; + +// This class encapsulates a VideoCaptureImpl under test and the necessary +// accessory classes, namely: +// - a MockMojoVideoCaptureHost, mimicking the RendererHost; +// - a few callbacks that are bound when calling operations of VideoCaptureImpl +// and on which we set expectations. +class VideoCaptureImplTest : public ::testing::Test { + public: + VideoCaptureImplTest() + : video_capture_impl_(new VideoCaptureImpl(session_id_)) { + params_small_.requested_format = media::VideoCaptureFormat( + gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420); + params_large_.requested_format = media::VideoCaptureFormat( + gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); + + video_capture_impl_->SetVideoCaptureHostForTesting( + &mock_video_capture_host_); + + ON_CALL(mock_video_capture_host_, DoStart(_, _, _)) + .WillByDefault(InvokeWithoutArgs([this]() { + video_capture_impl_->OnStateChanged( + media::mojom::VideoCaptureState::STARTED); + })); + } + + protected: + // These four mocks are used to create callbacks for the different oeprations. + MOCK_METHOD2(OnFrameReady, + void(scoped_refptr<media::VideoFrame>, base::TimeTicks)); + MOCK_METHOD1(OnStateUpdate, void(VideoCaptureState)); + MOCK_METHOD1(OnDeviceFormatsInUse, + void(const Vector<media::VideoCaptureFormat>&)); + MOCK_METHOD1(OnDeviceSupportedFormats, + void(const Vector<media::VideoCaptureFormat>&)); + + void StartCapture(int client_id, const media::VideoCaptureParams& params) { + const auto state_update_callback = base::Bind( + &VideoCaptureImplTest::OnStateUpdate, base::Unretained(this)); + const auto frame_ready_callback = + base::Bind(&VideoCaptureImplTest::OnFrameReady, base::Unretained(this)); + + video_capture_impl_->StartCapture(client_id, params, state_update_callback, + frame_ready_callback); + } + + void StopCapture(int client_id) { + video_capture_impl_->StopCapture(client_id); + } + + void SimulateOnBufferCreated(int buffer_id, + const base::UnsafeSharedMemoryRegion& region) { + video_capture_impl_->OnNewBuffer( + buffer_id, + media::mojom::blink::VideoBufferHandle::NewSharedBufferHandle( + mojo::WrapUnsafeSharedMemoryRegion(region.Duplicate()))); + } + + void SimulateReadOnlyBufferCreated(int buffer_id, + base::ReadOnlySharedMemoryRegion region) { + video_capture_impl_->OnNewBuffer( + buffer_id, + media::mojom::blink::VideoBufferHandle::NewReadOnlyShmemRegion( + std::move(region))); + } + + void SimulateBufferReceived(int buffer_id, const gfx::Size& size) { + media::mojom::blink::VideoFrameInfoPtr info = + media::mojom::blink::VideoFrameInfo::New(); + + const base::TimeTicks now = base::TimeTicks::Now(); + media::VideoFrameMetadata frame_metadata; + frame_metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, now); + info->metadata = frame_metadata.GetInternalValues().Clone(); + + info->timestamp = now - base::TimeTicks(); + info->pixel_format = media::PIXEL_FORMAT_I420; + info->coded_size = WebSize(size); + info->visible_rect = WebRect(gfx::Rect(size)); + + video_capture_impl_->OnBufferReady(buffer_id, std::move(info)); + } + + void SimulateBufferDestroyed(int buffer_id) { + video_capture_impl_->OnBufferDestroyed(buffer_id); + } + + void GetDeviceSupportedFormats() { + const base::Callback<void(const Vector<media::VideoCaptureFormat>&)> + callback = base::Bind(&VideoCaptureImplTest::OnDeviceSupportedFormats, + base::Unretained(this)); + video_capture_impl_->GetDeviceSupportedFormats(callback); + } + + void GetDeviceFormatsInUse() { + const base::Callback<void(const Vector<media::VideoCaptureFormat>&)> + callback = base::Bind(&VideoCaptureImplTest::OnDeviceFormatsInUse, + base::Unretained(this)); + video_capture_impl_->GetDeviceFormatsInUse(callback); + } + + void OnStateChanged(media::mojom::VideoCaptureState state) { + video_capture_impl_->OnStateChanged(state); + } + + const base::UnguessableToken session_id_ = base::UnguessableToken::Create(); + base::test::TaskEnvironment task_environment_; + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + const std::unique_ptr<VideoCaptureImpl> video_capture_impl_; + MockMojoVideoCaptureHost mock_video_capture_host_; + media::VideoCaptureParams params_small_; + media::VideoCaptureParams params_large_; + + private: + DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest); +}; + +TEST_F(VideoCaptureImplTest, Simple) { + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + + StartCapture(0, params_small_); + StopCapture(0); +} + +TEST_F(VideoCaptureImplTest, TwoClientsInSequence) { + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)) + .Times(2); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + + StartCapture(0, params_small_); + StopCapture(0); + StartCapture(1, params_small_); + StopCapture(1); +} + +TEST_F(VideoCaptureImplTest, LargeAndSmall) { + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)) + .Times(2); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_large_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + + StartCapture(0, params_large_); + StopCapture(0); + StartCapture(1, params_small_); + StopCapture(1); +} + +TEST_F(VideoCaptureImplTest, SmallAndLarge) { + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)) + .Times(2); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + + StartCapture(0, params_small_); + StopCapture(0); + StartCapture(1, params_large_); + StopCapture(1); +} + +// Checks that a request to GetDeviceSupportedFormats() ends up eventually in +// the provided callback. +TEST_F(VideoCaptureImplTest, GetDeviceFormats) { + EXPECT_CALL(*this, OnDeviceSupportedFormats(_)); + EXPECT_CALL(mock_video_capture_host_, + GetDeviceSupportedFormatsMock(_, session_id_, _)); + + GetDeviceSupportedFormats(); +} + +// Checks that two requests to GetDeviceSupportedFormats() end up eventually +// calling the provided callbacks. +TEST_F(VideoCaptureImplTest, TwoClientsGetDeviceFormats) { + EXPECT_CALL(*this, OnDeviceSupportedFormats(_)).Times(2); + EXPECT_CALL(mock_video_capture_host_, + GetDeviceSupportedFormatsMock(_, session_id_, _)) + .Times(2); + + GetDeviceSupportedFormats(); + GetDeviceSupportedFormats(); +} + +// Checks that a request to GetDeviceFormatsInUse() ends up eventually in the +// provided callback. +TEST_F(VideoCaptureImplTest, GetDeviceFormatsInUse) { + EXPECT_CALL(*this, OnDeviceFormatsInUse(_)); + EXPECT_CALL(mock_video_capture_host_, + GetDeviceFormatsInUseMock(_, session_id_, _)); + + GetDeviceFormatsInUse(); +} + +TEST_F(VideoCaptureImplTest, BufferReceived) { + const int kArbitraryBufferId = 11; + + const size_t frame_size = media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, params_small_.requested_format.frame_size); + base::UnsafeSharedMemoryRegion region = + base::UnsafeSharedMemoryRegion::Create(frame_size); + ASSERT_TRUE(region.IsValid()); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(*this, OnFrameReady(_, _)); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + EXPECT_CALL(mock_video_capture_host_, ReleaseBuffer(_, kArbitraryBufferId, _)) + .Times(0); + + StartCapture(0, params_small_); + SimulateOnBufferCreated(kArbitraryBufferId, region); + SimulateBufferReceived(kArbitraryBufferId, + params_small_.requested_format.frame_size); + StopCapture(0); + SimulateBufferDestroyed(kArbitraryBufferId); + + EXPECT_EQ(mock_video_capture_host_.released_buffer_count(), 0); +} + +TEST_F(VideoCaptureImplTest, BufferReceived_ReadOnlyShmemRegion) { + const int kArbitraryBufferId = 11; + + const size_t frame_size = media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, params_small_.requested_format.frame_size); + base::MappedReadOnlyRegion shm = + base::ReadOnlySharedMemoryRegion::Create(frame_size); + ASSERT_TRUE(shm.IsValid()); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(*this, OnFrameReady(_, _)); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + EXPECT_CALL(mock_video_capture_host_, ReleaseBuffer(_, kArbitraryBufferId, _)) + .Times(0); + + StartCapture(0, params_small_); + SimulateReadOnlyBufferCreated(kArbitraryBufferId, std::move(shm.region)); + SimulateBufferReceived(kArbitraryBufferId, + params_small_.requested_format.frame_size); + StopCapture(0); + SimulateBufferDestroyed(kArbitraryBufferId); + + EXPECT_EQ(mock_video_capture_host_.released_buffer_count(), 0); +} + +TEST_F(VideoCaptureImplTest, BufferReceivedAfterStop) { + const int kArbitraryBufferId = 12; + + const size_t frame_size = media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, params_large_.requested_format.frame_size); + base::UnsafeSharedMemoryRegion region = + base::UnsafeSharedMemoryRegion::Create(frame_size); + ASSERT_TRUE(region.IsValid()); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(*this, OnFrameReady(_, _)).Times(0); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_large_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + EXPECT_CALL(mock_video_capture_host_, + ReleaseBuffer(_, kArbitraryBufferId, _)); + + StartCapture(0, params_large_); + SimulateOnBufferCreated(kArbitraryBufferId, region); + StopCapture(0); + // A buffer received after StopCapture() triggers an instant ReleaseBuffer(). + SimulateBufferReceived(kArbitraryBufferId, + params_large_.requested_format.frame_size); + SimulateBufferDestroyed(kArbitraryBufferId); + + EXPECT_EQ(mock_video_capture_host_.released_buffer_count(), 1); +} + +TEST_F(VideoCaptureImplTest, BufferReceivedAfterStop_ReadOnlyShmemRegion) { + const int kArbitraryBufferId = 12; + + const size_t frame_size = media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, params_large_.requested_format.frame_size); + base::MappedReadOnlyRegion shm = + base::ReadOnlySharedMemoryRegion::Create(frame_size); + ASSERT_TRUE(shm.IsValid()); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(*this, OnFrameReady(_, _)).Times(0); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_large_)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + EXPECT_CALL(mock_video_capture_host_, + ReleaseBuffer(_, kArbitraryBufferId, _)); + + StartCapture(0, params_large_); + SimulateReadOnlyBufferCreated(kArbitraryBufferId, std::move(shm.region)); + StopCapture(0); + // A buffer received after StopCapture() triggers an instant ReleaseBuffer(). + SimulateBufferReceived(kArbitraryBufferId, + params_large_.requested_format.frame_size); + SimulateBufferDestroyed(kArbitraryBufferId); + + EXPECT_EQ(mock_video_capture_host_.released_buffer_count(), 1); +} + +TEST_F(VideoCaptureImplTest, AlreadyStarted) { + media::VideoCaptureParams params = {}; + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)) + .Times(2); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)) + .WillOnce(DoAll(InvokeWithoutArgs([this]() { + video_capture_impl_->OnStateChanged( + media::mojom::VideoCaptureState::STARTED); + }), + SaveArg<2>(¶ms))); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + + StartCapture(0, params_small_); + StartCapture(1, params_large_); + StopCapture(0); + StopCapture(1); + DCHECK(params.requested_format == params_small_.requested_format); +} + +TEST_F(VideoCaptureImplTest, EndedBeforeStop) { + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + + StartCapture(0, params_small_); + + OnStateChanged(media::mojom::VideoCaptureState::ENDED); + + StopCapture(0); +} + +TEST_F(VideoCaptureImplTest, ErrorBeforeStop) { + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_ERROR)); + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)); + + StartCapture(0, params_small_); + + OnStateChanged(media::mojom::VideoCaptureState::FAILED); + + StopCapture(0); +} + +TEST_F(VideoCaptureImplTest, BufferReceivedBeforeOnStarted) { + const int kArbitraryBufferId = 16; + + const size_t frame_size = media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, params_small_.requested_format.frame_size); + base::UnsafeSharedMemoryRegion region = + base::UnsafeSharedMemoryRegion::Create(frame_size); + ASSERT_TRUE(region.IsValid()); + + InSequence s; + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)) + .WillOnce(DoNothing()); + EXPECT_CALL(mock_video_capture_host_, + ReleaseBuffer(_, kArbitraryBufferId, _)); + StartCapture(0, params_small_); + SimulateOnBufferCreated(kArbitraryBufferId, region); + SimulateBufferReceived(kArbitraryBufferId, + params_small_.requested_format.frame_size); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(mock_video_capture_host_, RequestRefreshFrame(_)); + video_capture_impl_->OnStateChanged(media::mojom::VideoCaptureState::STARTED); + + // Additional STARTED will cause RequestRefreshFrame a second time. + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(mock_video_capture_host_, RequestRefreshFrame(_)); + video_capture_impl_->OnStateChanged(media::mojom::VideoCaptureState::STARTED); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + StopCapture(0); +} + +TEST_F(VideoCaptureImplTest, + BufferReceivedBeforeOnStarted_ReadOnlyShmemRegion) { + const int kArbitraryBufferId = 16; + + const size_t frame_size = media::VideoFrame::AllocationSize( + media::PIXEL_FORMAT_I420, params_small_.requested_format.frame_size); + base::MappedReadOnlyRegion shm = + base::ReadOnlySharedMemoryRegion::Create(frame_size); + ASSERT_TRUE(shm.IsValid()); + + InSequence s; + EXPECT_CALL(mock_video_capture_host_, DoStart(_, session_id_, params_small_)) + .WillOnce(DoNothing()); + EXPECT_CALL(mock_video_capture_host_, + ReleaseBuffer(_, kArbitraryBufferId, _)); + StartCapture(0, params_small_); + SimulateReadOnlyBufferCreated(kArbitraryBufferId, std::move(shm.region)); + SimulateBufferReceived(kArbitraryBufferId, + params_small_.requested_format.frame_size); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(mock_video_capture_host_, RequestRefreshFrame(_)); + video_capture_impl_->OnStateChanged(media::mojom::VideoCaptureState::STARTED); + + // Additional STARTED will cause RequestRefreshFrame a second time. + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STARTED)); + EXPECT_CALL(mock_video_capture_host_, RequestRefreshFrame(_)); + video_capture_impl_->OnStateChanged(media::mojom::VideoCaptureState::STARTED); + + EXPECT_CALL(*this, OnStateUpdate(blink::VIDEO_CAPTURE_STATE_STOPPED)); + EXPECT_CALL(mock_video_capture_host_, Stop(_)); + StopCapture(0); +} + +} // namespace blink |