Chromium Code Reviews| Index: media/capture/video/chromeos/camera_device_delegate_unittest.cc |
| diff --git a/media/capture/video/chromeos/camera_device_delegate_unittest.cc b/media/capture/video/chromeos/camera_device_delegate_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ca9b24f4d038928a3f1b3b40478d7b4190c7ce42 |
| --- /dev/null |
| +++ b/media/capture/video/chromeos/camera_device_delegate_unittest.cc |
| @@ -0,0 +1,547 @@ |
| +// Copyright 2017 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 "media/capture/video/chromeos/camera_device_delegate.h" |
| + |
| +#include <stddef.h> |
| +#include <stdint.h> |
| + |
| +#include <memory> |
| +#include <utility> |
| + |
| +#include "base/run_loop.h" |
| +#include "base/test/scoped_task_environment.h" |
| +#include "media/base/bind_to_current_loop.h" |
| +#include "media/capture/video/chromeos/camera_hal_delegate.h" |
| +#include "media/capture/video/chromeos/mock_camera_module.h" |
| +#include "media/capture/video/chromeos/mojo/arc_camera3.mojom.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +using testing::_; |
| +using testing::A; |
| +using testing::AtLeast; |
| +using testing::Invoke; |
| +using testing::InvokeWithoutArgs; |
| + |
| +namespace media { |
| + |
| +namespace { |
| + |
| +void DumpError(const tracked_objects::Location& location, |
| + const std::string& message) { |
| + DPLOG(ERROR) << location.ToString() << " " << message; |
| +} |
| + |
| +class MockVideoCaptureClient : public VideoCaptureDevice::Client { |
| + public: |
| + MOCK_METHOD0(DoReserveOutputBuffer, void(void)); |
| + MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void)); |
| + MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void)); |
| + MOCK_METHOD0(DoResurrectLastOutputBuffer, void(void)); |
| + MOCK_METHOD2(OnError, |
| + void(const tracked_objects::Location& from_here, |
| + const std::string& reason)); |
| + MOCK_CONST_METHOD0(GetBufferPoolUtilization, double(void)); |
| + MOCK_METHOD0(OnStarted, void(void)); |
| + |
| + explicit MockVideoCaptureClient(base::Callback<void()> quit_cb) |
| + : quit_cb_(quit_cb) { |
| + ON_CALL(*this, OnError(_, _)).WillByDefault(Invoke(DumpError)); |
| + } |
| + |
| + ~MockVideoCaptureClient() { quit_cb_.Run(); } |
| + |
| + void OnIncomingCapturedData(const uint8_t* data, |
| + int length, |
| + const VideoCaptureFormat& format, |
| + int rotation, |
| + base::TimeTicks reference_time, |
| + base::TimeDelta timestamp, |
| + int frame_feedback_id) override { |
| + ASSERT_GT(length, 0); |
| + ASSERT_TRUE(data); |
| + quit_cb_.Run(); |
| + } |
| + |
| + // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>. |
| + Buffer ReserveOutputBuffer(const gfx::Size& dimensions, |
| + media::VideoPixelFormat format, |
| + media::VideoPixelStorage storage, |
| + int frame_feedback_id) override { |
| + DoReserveOutputBuffer(); |
| + NOTREACHED() << "This should never be called"; |
| + return Buffer(); |
| + } |
| + void OnIncomingCapturedBuffer(Buffer buffer, |
| + const VideoCaptureFormat& format, |
| + base::TimeTicks reference_time, |
| + base::TimeDelta timestamp) override { |
| + DoOnIncomingCapturedBuffer(); |
| + } |
| + void OnIncomingCapturedBufferExt( |
| + Buffer buffer, |
| + const VideoCaptureFormat& format, |
| + base::TimeTicks reference_time, |
| + base::TimeDelta timestamp, |
| + gfx::Rect visible_rect, |
| + const VideoFrameMetadata& additional_metadata) override { |
| + DoOnIncomingCapturedVideoFrame(); |
| + } |
| + Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions, |
| + media::VideoPixelFormat format, |
| + media::VideoPixelStorage storage, |
| + int frame_feedback_id) { |
| + DoResurrectLastOutputBuffer(); |
| + NOTREACHED() << "This should never be called"; |
| + return Buffer(); |
| + } |
| + |
| + private: |
| + base::Callback<void()> quit_cb_; |
| +}; |
| + |
| +class MockCameraDevice : public arc::mojom::Camera3DeviceOps { |
| + public: |
| + MockCameraDevice() {} |
| + |
| + ~MockCameraDevice() {} |
| + |
| + void Initialize(arc::mojom::Camera3CallbackOpsPtr callback_ops, |
| + InitializeCallback callback) override { |
| + DoInitialize(callback_ops, callback); |
| + } |
| + MOCK_METHOD2(DoInitialize, |
| + void(arc::mojom::Camera3CallbackOpsPtr& callback_ops, |
| + InitializeCallback& callback)); |
| + |
| + void ConfigureStreams(arc::mojom::Camera3StreamConfigurationPtr config, |
| + ConfigureStreamsCallback callback) override { |
| + DoConfigureStreams(config, callback); |
| + } |
| + MOCK_METHOD2(DoConfigureStreams, |
| + void(arc::mojom::Camera3StreamConfigurationPtr& config, |
| + ConfigureStreamsCallback& callback)); |
| + |
| + void ConstructDefaultRequestSettings( |
| + arc::mojom::Camera3RequestTemplate type, |
| + ConstructDefaultRequestSettingsCallback callback) override { |
| + DoConstructDefaultRequestSettings(type, callback); |
| + } |
| + MOCK_METHOD2(DoConstructDefaultRequestSettings, |
| + void(arc::mojom::Camera3RequestTemplate type, |
| + ConstructDefaultRequestSettingsCallback& callback)); |
| + |
| + void ProcessCaptureRequest(arc::mojom::Camera3CaptureRequestPtr request, |
| + ProcessCaptureRequestCallback callback) override { |
| + DoProcessCaptureRequest(request, callback); |
| + } |
| + MOCK_METHOD2(DoProcessCaptureRequest, |
| + void(arc::mojom::Camera3CaptureRequestPtr& request, |
| + ProcessCaptureRequestCallback& callback)); |
| + |
| + void Dump(mojo::ScopedHandle fd) override { DoDump(fd); } |
| + MOCK_METHOD1(DoDump, void(mojo::ScopedHandle& fd)); |
| + |
| + void Flush(FlushCallback callback) override { DoFlush(callback); } |
| + MOCK_METHOD1(DoFlush, void(FlushCallback& callback)); |
| + |
| + void RegisterBuffer(uint64_t buffer_id, |
| + arc::mojom::Camera3DeviceOps::BufferType type, |
| + std::vector<mojo::ScopedHandle> fds, |
| + uint32_t drm_format, |
| + arc::mojom::HalPixelFormat hal_pixel_format, |
| + uint32_t width, |
| + uint32_t height, |
| + const std::vector<uint32_t>& strides, |
| + const std::vector<uint32_t>& offsets, |
| + RegisterBufferCallback callback) override { |
| + DoRegisterBuffer(buffer_id, type, fds, drm_format, hal_pixel_format, width, |
| + height, strides, offsets, callback); |
| + } |
| + MOCK_METHOD10(DoRegisterBuffer, |
| + void(uint64_t buffer_id, |
| + arc::mojom::Camera3DeviceOps::BufferType type, |
| + std::vector<mojo::ScopedHandle>& fds, |
| + uint32_t drm_format, |
| + arc::mojom::HalPixelFormat hal_pixel_format, |
| + uint32_t width, |
| + uint32_t height, |
| + const std::vector<uint32_t>& strides, |
| + const std::vector<uint32_t>& offsets, |
| + RegisterBufferCallback& callback)); |
| + |
| + void Close(CloseCallback callback) override { DoClose(callback); } |
| + MOCK_METHOD1(DoClose, void(CloseCallback& callback)); |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MockCameraDevice); |
| +}; |
| + |
| +const VideoCaptureDeviceDescriptor kDefaultDescriptor("Fake device", "0"); |
| +const VideoCaptureFormat kDefaultCaptureFormat(gfx::Size(1280, 720), |
| + 30.0, |
| + PIXEL_FORMAT_I420); |
| + |
| +} // namespace |
| + |
| +class CameraDeviceDelegateTest : public ::testing::Test { |
| + public: |
| + CameraDeviceDelegateTest() |
| + : mock_camera_device_binding_(&mock_camera_device_), |
| + device_delegate_thread_("DeviceDelegateThread"), |
| + hal_delegate_thread_("HalDelegateThread") {} |
| + |
| + void SetUp() override { |
| + hal_delegate_thread_.Start(); |
| + camera_hal_delegate_ = |
| + new CameraHalDelegate(hal_delegate_thread_.task_runner()); |
| + camera_hal_delegate_->StartForTesting( |
| + mock_camera_module_.GetInterfacePtrInfo()); |
| + |
| + ResetCaptureClient(); |
| + } |
| + |
| + void TearDown() override { |
| + camera_hal_delegate_->Reset(); |
| + hal_delegate_thread_.Stop(); |
| + } |
| + |
| + void AllocateDeviceWithDescriptor(VideoCaptureDeviceDescriptor descriptor) { |
| + ASSERT_FALSE(device_delegate_thread_.IsRunning()); |
| + ASSERT_FALSE(camera_device_delegate_); |
| + device_delegate_thread_.Start(); |
| + camera_device_delegate_ = |
| + new CameraDeviceDelegate(descriptor, camera_hal_delegate_, |
| + device_delegate_thread_.task_runner()); |
| + } |
| + |
| + void GetFakeCameraInfo(uint32_t camera_id, |
| + arc::mojom::CameraModule::GetCameraInfoCallback& cb) { |
| + arc::mojom::CameraInfoPtr camera_info = arc::mojom::CameraInfo::New(); |
| + arc::mojom::CameraMetadataPtr static_metadata = |
| + arc::mojom::CameraMetadata::New(); |
| + switch (camera_id) { |
| + case 0: |
| + camera_info->facing = arc::mojom::CameraFacing::CAMERA_FACING_FRONT; |
| + camera_info->orientation = 0; |
| + camera_info->static_camera_characteristics = std::move(static_metadata); |
| + break; |
| + default: |
| + FAIL() << "Invalid camera id"; |
| + } |
| + std::move(cb).Run(0, std::move(camera_info)); |
| + } |
| + |
| + void OpenMockCameraDevice( |
| + int32_t camera_id, |
| + arc::mojom::Camera3DeviceOpsRequest& device_ops_request, |
| + base::OnceCallback<void(int32_t)>& callback) { |
| + mock_camera_device_binding_.Bind(std::move(device_ops_request)); |
| + std::move(callback).Run(0); |
| + } |
| + |
| + void InitializeMockCameraDevice( |
| + arc::mojom::Camera3CallbackOpsPtr& callback_ops, |
| + base::OnceCallback<void(int32_t)>& callback) { |
| + callback_ops_ = std::move(callback_ops); |
| + std::move(callback).Run(0); |
| + } |
| + |
| + void ConfigureFakeStreams( |
| + arc::mojom::Camera3StreamConfigurationPtr& config, |
| + base::OnceCallback< |
| + void(int32_t, arc::mojom::Camera3StreamConfigurationPtr)>& callback) { |
| + ASSERT_EQ(1u, config->streams.size()); |
| + ASSERT_EQ(static_cast<uint32_t>(kDefaultCaptureFormat.frame_size.width()), |
| + config->streams[0]->width); |
| + ASSERT_EQ(static_cast<uint32_t>(kDefaultCaptureFormat.frame_size.height()), |
| + config->streams[0]->height); |
| + ASSERT_EQ(arc::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888, |
| + config->streams[0]->format); |
| + config->streams[0]->usage = 0; |
| + config->streams[0]->max_buffers = 1; |
| + std::move(callback).Run(0, std::move(config)); |
| + } |
| + |
| + void ConstructFakeRequestSettings( |
| + arc::mojom::Camera3RequestTemplate type, |
| + base::OnceCallback<void(arc::mojom::CameraMetadataPtr)>& callback) { |
| + ASSERT_EQ(arc::mojom::Camera3RequestTemplate::CAMERA3_TEMPLATE_PREVIEW, |
| + type); |
| + arc::mojom::CameraMetadataPtr fake_settings = |
| + arc::mojom::CameraMetadata::New(); |
| + fake_settings->entry_count = 1; |
| + fake_settings->entry_capacity = 1; |
| + fake_settings->entries = std::vector<arc::mojom::CameraMetadataEntryPtr>(); |
| + std::move(callback).Run(std::move(fake_settings)); |
| + } |
| + |
| + void RegisterBuffer(uint64_t buffer_id, |
| + arc::mojom::Camera3DeviceOps::BufferType type, |
| + std::vector<mojo::ScopedHandle>& fds, |
| + uint32_t drm_format, |
| + arc::mojom::HalPixelFormat hal_pixel_format, |
| + uint32_t width, |
| + uint32_t height, |
| + const std::vector<uint32_t>& strides, |
| + const std::vector<uint32_t>& offsets, |
| + base::OnceCallback<void(int32_t)>& callback) { |
| + std::move(callback).Run(0); |
| + } |
| + |
| + void ProcessCaptureRequest(arc::mojom::Camera3CaptureRequestPtr& request, |
| + base::OnceCallback<void(int32_t)>& callback) { |
| + std::move(callback).Run(0); |
| + |
| + arc::mojom::Camera3NotifyMsgPtr msg = arc::mojom::Camera3NotifyMsg::New(); |
| + msg->type = arc::mojom::Camera3MsgType::CAMERA3_MSG_SHUTTER; |
| + msg->message = arc::mojom::Camera3NotifyMsgMessage::New(); |
| + arc::mojom::Camera3ShutterMsgPtr shutter_msg = |
| + arc::mojom::Camera3ShutterMsg::New(); |
| + shutter_msg->timestamp = base::TimeTicks::Now().ToInternalValue(); |
| + msg->message->set_shutter(std::move(shutter_msg)); |
| + callback_ops_->Notify(std::move(msg)); |
| + |
| + arc::mojom::Camera3CaptureResultPtr result = |
| + arc::mojom::Camera3CaptureResult::New(); |
| + result->frame_number = request->frame_number; |
| + result->result = arc::mojom::CameraMetadata::New(); |
| + result->output_buffers = std::move(request->output_buffers); |
| + result->partial_result = 1; |
| + callback_ops_->ProcessCaptureResult(std::move(result)); |
| + } |
| + |
| + void CloseMockCameraDevice(base::OnceCallback<void(int32_t)>& callback) { |
| + if (mock_camera_device_binding_.is_bound()) { |
| + mock_camera_device_binding_.Close(); |
| + } |
| + callback_ops_.reset(); |
| + std::move(callback).Run(0); |
| + } |
| + |
| + void SetUpExpectationUntilInitialized() { |
| + EXPECT_CALL(mock_camera_module_, DoGetCameraInfo(0, _)) |
| + .Times(1) |
| + .WillOnce(Invoke(this, &CameraDeviceDelegateTest::GetFakeCameraInfo)); |
| + EXPECT_CALL(mock_camera_module_, DoOpenDevice(0, _, _)) |
| + .Times(1) |
| + .WillOnce( |
| + Invoke(this, &CameraDeviceDelegateTest::OpenMockCameraDevice)); |
| + EXPECT_CALL(mock_camera_device_, DoInitialize(_, _)) |
| + .Times(1) |
| + .WillOnce(Invoke( |
| + this, &CameraDeviceDelegateTest::InitializeMockCameraDevice)); |
| + } |
| + |
| + void SetUpExpectationUntilStreamConfigured() { |
| + SetUpExpectationUntilInitialized(); |
| + EXPECT_CALL(mock_camera_device_, DoConfigureStreams(_, _)) |
| + .Times(1) |
| + .WillOnce( |
| + Invoke(this, &CameraDeviceDelegateTest::ConfigureFakeStreams)); |
| + } |
| + |
| + void SetUpExpectationUntilCapturing(MockVideoCaptureClient* mock_client) { |
| + SetUpExpectationUntilStreamConfigured(); |
| + EXPECT_CALL(mock_camera_device_, DoConstructDefaultRequestSettings(_, _)) |
| + .Times(1) |
| + .WillOnce(Invoke( |
| + this, &CameraDeviceDelegateTest::ConstructFakeRequestSettings)); |
| + EXPECT_CALL(*mock_client, OnStarted()).Times(1); |
| + } |
| + |
| + void SetUpExpectationForCaptureLoop() { |
| + EXPECT_CALL(mock_camera_device_, |
| + DoRegisterBuffer(_, _, _, _, _, _, _, _, _, _)) |
| + .Times(AtLeast(1)) |
| + .WillOnce(Invoke(this, &CameraDeviceDelegateTest::RegisterBuffer)) |
| + .WillRepeatedly( |
| + Invoke(this, &CameraDeviceDelegateTest::RegisterBuffer)); |
| + EXPECT_CALL(mock_camera_device_, DoProcessCaptureRequest(_, _)) |
| + .Times(AtLeast(1)) |
| + .WillOnce( |
| + Invoke(this, &CameraDeviceDelegateTest::ProcessCaptureRequest)) |
| + .WillRepeatedly( |
| + Invoke(this, &CameraDeviceDelegateTest::ProcessCaptureRequest)); |
| + } |
| + |
| + void SetUpExpectationForClose() { |
| + EXPECT_CALL(mock_camera_device_, DoClose(_)) |
| + .Times(1) |
| + .WillOnce( |
| + Invoke(this, &CameraDeviceDelegateTest::CloseMockCameraDevice)); |
| + } |
| + |
| + void ResetCaptureClient() { |
| + mock_client_.reset( |
| + new MockVideoCaptureClient(BindToCurrentLoop(base::BindRepeating( |
| + &CameraDeviceDelegateTest::QuitRunLoop, base::Unretained(this))))); |
| + } |
| + |
| + void ResetDevice() { |
| + ASSERT_TRUE(device_delegate_thread_.IsRunning()); |
| + ASSERT_TRUE(camera_device_delegate_); |
| + while (!camera_device_delegate_->HasOneRef()) { |
| + base::PlatformThread::YieldCurrentThread(); |
| + } |
| + camera_device_delegate_ = nullptr; |
| + device_delegate_thread_.Stop(); |
| + } |
| + |
| + void DoLoop() { |
| + run_loop_.reset(new base::RunLoop()); |
| + run_loop_->Run(); |
| + } |
| + |
| + void QuitRunLoop() { |
| + if (run_loop_) { |
| + run_loop_->Quit(); |
| + } |
| + } |
| + |
| + CameraDeviceDelegate::State GetState() { |
| + return camera_device_delegate_->state_; |
| + } |
| + |
| + protected: |
| + scoped_refptr<CameraHalDelegate> camera_hal_delegate_; |
| + scoped_refptr<CameraDeviceDelegate> camera_device_delegate_; |
| + |
| + testing::StrictMock<unittest_internal::MockCameraModule> mock_camera_module_; |
| + |
| + testing::StrictMock<MockCameraDevice> mock_camera_device_; |
| + mojo::Binding<arc::mojom::Camera3DeviceOps> mock_camera_device_binding_; |
| + arc::mojom::Camera3CallbackOpsPtr callback_ops_; |
| + |
| + base::Thread device_delegate_thread_; |
| + |
| + std::unique_ptr<VideoCaptureDevice::Client> mock_client_; |
| + |
| + private: |
| + base::test::ScopedTaskEnvironment scoped_task_environment_; |
| + base::Thread hal_delegate_thread_; |
| + std::unique_ptr<base::RunLoop> run_loop_; |
| + DISALLOW_COPY_AND_ASSIGN(CameraDeviceDelegateTest); |
| +}; |
| + |
| +TEST_F(CameraDeviceDelegateTest, AllocateCaptureAndStop) { |
| + AllocateDeviceWithDescriptor(kDefaultDescriptor); |
| + |
| + VideoCaptureParams params; |
| + params.requested_format = kDefaultCaptureFormat; |
| + |
| + SetUpExpectationUntilCapturing( |
| + reinterpret_cast<MockVideoCaptureClient*>(mock_client_.get())); |
| + SetUpExpectationForCaptureLoop(); |
| + |
| + device_delegate_thread_.task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&CameraDeviceDelegate::AllocateAndStart, |
| + camera_device_delegate_, params, base::Passed(&mock_client_))); |
| + |
| + // Wait until a frame is received. |mock_client_| calls OnFrameCaptured() to |
| + // stop the run loop. |
| + DoLoop(); |
| + EXPECT_EQ(CameraDeviceDelegate::State::kCapturing, GetState()); |
| + |
| + SetUpExpectationForClose(); |
| + |
| + device_delegate_thread_.task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&CameraDeviceDelegate::StopAndDeAllocate, |
| + camera_device_delegate_)); |
| + |
| + // Wait until |mock_client_| is deleted. |
| + DoLoop(); |
| + EXPECT_EQ(CameraDeviceDelegate::State::kStopped, GetState()); |
| + |
| + ResetDevice(); |
| +} |
| + |
| +TEST_F(CameraDeviceDelegateTest, StopAfterInitialized) { |
|
chfremer
2017/06/06 17:09:25
For readers of the could, I found it helpful to ad
jcliang
2017/06/07 08:18:39
Done.
|
| + AllocateDeviceWithDescriptor(kDefaultDescriptor); |
| + |
| + VideoCaptureParams params; |
| + params.requested_format = kDefaultCaptureFormat; |
| + |
| + SetUpExpectationUntilInitialized(); |
| + |
| + device_delegate_thread_.task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&CameraDeviceDelegate::AllocateAndStart, |
| + camera_device_delegate_, params, base::Passed(&mock_client_))); |
| + |
| + auto stop_on_configure_stream = |
|
chfremer
2017/06/06 17:09:25
Separating the lambda into a temporary variable li
jcliang
2017/06/07 08:18:40
Done.
|
| + [this]( |
| + arc::mojom::Camera3StreamConfigurationPtr& config, |
| + base::OnceCallback<void( |
| + int32_t, arc::mojom::Camera3StreamConfigurationPtr)>& callback) { |
| + EXPECT_EQ(CameraDeviceDelegate::State::kInitialized, this->GetState()); |
| + this->QuitRunLoop(); |
| + std::move(callback).Run(0, |
| + arc::mojom::Camera3StreamConfiguration::New()); |
| + }; |
| + EXPECT_CALL(mock_camera_device_, DoConfigureStreams(_, _)) |
| + .Times(1) |
| + .WillOnce(Invoke(stop_on_configure_stream)); |
| + |
| + // Wait until the QuitRunLoop call in |mock_camera_device_->ConfigureStreams|. |
| + DoLoop(); |
| + |
| + SetUpExpectationForClose(); |
| + |
| + device_delegate_thread_.task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&CameraDeviceDelegate::StopAndDeAllocate, |
| + camera_device_delegate_)); |
| + |
| + // Wait until |mock_client_| is deleted. |
| + DoLoop(); |
| + EXPECT_EQ(CameraDeviceDelegate::State::kStopped, GetState()); |
| + |
| + ResetDevice(); |
| +} |
| + |
| +TEST_F(CameraDeviceDelegateTest, StopAfterStreamConfigured) { |
| + AllocateDeviceWithDescriptor(kDefaultDescriptor); |
| + |
| + VideoCaptureParams params; |
| + params.requested_format = kDefaultCaptureFormat; |
| + |
| + SetUpExpectationUntilStreamConfigured(); |
| + |
| + device_delegate_thread_.task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&CameraDeviceDelegate::AllocateAndStart, |
| + camera_device_delegate_, params, base::Passed(&mock_client_))); |
| + |
| + auto stop_on_construct_default_request_settings = |
| + [this]( |
| + arc::mojom::Camera3RequestTemplate type, |
| + base::OnceCallback<void(arc::mojom::CameraMetadataPtr)>& callback) { |
| + EXPECT_EQ(CameraDeviceDelegate::State::kStreamConfigured, |
| + this->GetState()); |
| + this->QuitRunLoop(); |
| + std::move(callback).Run(arc::mojom::CameraMetadataPtr()); |
| + }; |
| + EXPECT_CALL(mock_camera_device_, DoConstructDefaultRequestSettings(_, _)) |
| + .Times(1) |
| + .WillOnce(Invoke(stop_on_construct_default_request_settings)); |
| + |
| + // Wait until the QuitRunLoop call in |mock_camera_device_->ConfigureStreams|. |
| + DoLoop(); |
| + |
| + SetUpExpectationForClose(); |
| + |
| + device_delegate_thread_.task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&CameraDeviceDelegate::StopAndDeAllocate, |
| + camera_device_delegate_)); |
| + |
| + // Wait until |mock_client_| is deleted. |
| + DoLoop(); |
| + EXPECT_EQ(CameraDeviceDelegate::State::kStopped, GetState()); |
| + |
| + ResetDevice(); |
| +} |
| + |
| +} // namespace media |