/* * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/desktop_capture/fallback_desktop_capturer_wrapper.h" #include #include #include #include #include "modules/desktop_capture/desktop_capturer.h" #include "modules/desktop_capture/desktop_frame_generator.h" #include "modules/desktop_capture/fake_desktop_capturer.h" #include "test/gtest.h" namespace webrtc { namespace { std::unique_ptr CreateDesktopCapturer( PainterDesktopFrameGenerator* frame_generator) { std::unique_ptr capturer(new FakeDesktopCapturer()); capturer->set_frame_generator(frame_generator); return std::move(capturer); } class FakeSharedMemory : public SharedMemory { public: explicit FakeSharedMemory(size_t size); ~FakeSharedMemory() override; private: static int next_id_; }; // static int FakeSharedMemory::next_id_ = 0; FakeSharedMemory::FakeSharedMemory(size_t size) : SharedMemory(new char[size], size, 0, next_id_++) {} FakeSharedMemory::~FakeSharedMemory() { delete[] static_cast(data_); } class FakeSharedMemoryFactory : public SharedMemoryFactory { public: FakeSharedMemoryFactory() = default; ~FakeSharedMemoryFactory() override = default; std::unique_ptr CreateSharedMemory(size_t size) override; }; std::unique_ptr FakeSharedMemoryFactory::CreateSharedMemory( size_t size) { return std::unique_ptr(new FakeSharedMemory(size)); } } // namespace class FallbackDesktopCapturerWrapperTest : public ::testing::Test, public DesktopCapturer::Callback { public: FallbackDesktopCapturerWrapperTest(); ~FallbackDesktopCapturerWrapperTest() override = default; protected: std::vector> results_; FakeDesktopCapturer* main_capturer_ = nullptr; FakeDesktopCapturer* secondary_capturer_ = nullptr; std::unique_ptr wrapper_; private: // DesktopCapturer::Callback interface void OnCaptureResult(DesktopCapturer::Result result, std::unique_ptr frame) override; PainterDesktopFrameGenerator frame_generator_; }; FallbackDesktopCapturerWrapperTest::FallbackDesktopCapturerWrapperTest() { frame_generator_.size()->set(1024, 768); std::unique_ptr main_capturer = CreateDesktopCapturer(&frame_generator_); std::unique_ptr secondary_capturer = CreateDesktopCapturer(&frame_generator_); main_capturer_ = static_cast(main_capturer.get()); secondary_capturer_ = static_cast(secondary_capturer.get()); wrapper_.reset(new FallbackDesktopCapturerWrapper( std::move(main_capturer), std::move(secondary_capturer))); wrapper_->Start(this); } void FallbackDesktopCapturerWrapperTest::OnCaptureResult( DesktopCapturer::Result result, std::unique_ptr frame) { results_.emplace_back(result, !!frame); } TEST_F(FallbackDesktopCapturerWrapperTest, MainNeverFailed) { wrapper_->CaptureFrame(); ASSERT_EQ(main_capturer_->num_capture_attempts(), 1); ASSERT_EQ(main_capturer_->num_frames_captured(), 1); ASSERT_EQ(secondary_capturer_->num_capture_attempts(), 0); ASSERT_EQ(secondary_capturer_->num_frames_captured(), 0); ASSERT_EQ(results_.size(), 1U); ASSERT_EQ(results_[0], std::make_pair(DesktopCapturer::Result::SUCCESS, true)); } TEST_F(FallbackDesktopCapturerWrapperTest, MainFailedTemporarily) { wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::ERROR_TEMPORARY); wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::SUCCESS); wrapper_->CaptureFrame(); ASSERT_EQ(main_capturer_->num_capture_attempts(), 3); ASSERT_EQ(main_capturer_->num_frames_captured(), 2); ASSERT_EQ(secondary_capturer_->num_capture_attempts(), 1); ASSERT_EQ(secondary_capturer_->num_frames_captured(), 1); ASSERT_EQ(results_.size(), 3U); for (int i = 0; i < 3; i++) { ASSERT_EQ(results_[i], std::make_pair(DesktopCapturer::Result::SUCCESS, true)); } } TEST_F(FallbackDesktopCapturerWrapperTest, MainFailedPermanently) { wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::ERROR_PERMANENT); wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::SUCCESS); wrapper_->CaptureFrame(); ASSERT_EQ(main_capturer_->num_capture_attempts(), 2); ASSERT_EQ(main_capturer_->num_frames_captured(), 1); ASSERT_EQ(secondary_capturer_->num_capture_attempts(), 2); ASSERT_EQ(secondary_capturer_->num_frames_captured(), 2); ASSERT_EQ(results_.size(), 3U); for (int i = 0; i < 3; i++) { ASSERT_EQ(results_[i], std::make_pair(DesktopCapturer::Result::SUCCESS, true)); } } TEST_F(FallbackDesktopCapturerWrapperTest, BothFailed) { wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::ERROR_PERMANENT); wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::SUCCESS); wrapper_->CaptureFrame(); secondary_capturer_->set_result(DesktopCapturer::Result::ERROR_TEMPORARY); wrapper_->CaptureFrame(); secondary_capturer_->set_result(DesktopCapturer::Result::ERROR_PERMANENT); wrapper_->CaptureFrame(); wrapper_->CaptureFrame(); ASSERT_EQ(main_capturer_->num_capture_attempts(), 2); ASSERT_EQ(main_capturer_->num_frames_captured(), 1); ASSERT_EQ(secondary_capturer_->num_capture_attempts(), 5); ASSERT_EQ(secondary_capturer_->num_frames_captured(), 2); ASSERT_EQ(results_.size(), 6U); for (int i = 0; i < 3; i++) { ASSERT_EQ(results_[i], std::make_pair(DesktopCapturer::Result::SUCCESS, true)); } ASSERT_EQ(results_[3], std::make_pair(DesktopCapturer::Result::ERROR_TEMPORARY, false)); ASSERT_EQ(results_[4], std::make_pair(DesktopCapturer::Result::ERROR_PERMANENT, false)); ASSERT_EQ(results_[5], std::make_pair(DesktopCapturer::Result::ERROR_PERMANENT, false)); } TEST_F(FallbackDesktopCapturerWrapperTest, WithSharedMemory) { wrapper_->SetSharedMemoryFactory( std::unique_ptr(new FakeSharedMemoryFactory())); wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::ERROR_TEMPORARY); wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::SUCCESS); wrapper_->CaptureFrame(); main_capturer_->set_result(DesktopCapturer::Result::ERROR_PERMANENT); wrapper_->CaptureFrame(); wrapper_->CaptureFrame(); ASSERT_EQ(main_capturer_->num_capture_attempts(), 4); ASSERT_EQ(main_capturer_->num_frames_captured(), 2); ASSERT_EQ(secondary_capturer_->num_capture_attempts(), 3); ASSERT_EQ(secondary_capturer_->num_frames_captured(), 3); ASSERT_EQ(results_.size(), 5U); for (int i = 0; i < 5; i++) { ASSERT_EQ(results_[i], std::make_pair(DesktopCapturer::Result::SUCCESS, true)); } } } // namespace webrtc