#include "third_party/blink/renderer/platform/media/web_media_player_impl.h"
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>
#include "base/command_line.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "cc/layers/layer.h"
#include "components/viz/test/test_context_provider.h"
#include "media/base/decoder_buffer.h"
#include "media/base/key_systems_impl.h"
#include "media/base/media_content_type.h"
#include "media/base/media_log.h"
#include "media/base/media_observer.h"
#include "media/base/media_switches.h"
#include "media/base/memory_dump_provider_proxy.h"
#include "media/base/mock_audio_renderer_sink.h"
#include "media/base/mock_filters.h"
#include "media/base/mock_media_log.h"
#include "media/base/test_data_util.h"
#include "media/base/test_helpers.h"
#include "media/cdm/clear_key_cdm_common.h"
#include "media/filters/pipeline_controller.h"
#include "media/mojo/services/media_metrics_provider.h"
#include "media/mojo/services/video_decode_stats_recorder.h"
#include "media/mojo/services/watch_time_recorder.h"
#include "media/renderers/default_decoder_factory.h"
#include "media/renderers/renderer_impl_factory.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/platform/media/web_media_player_builder.h"
#include "third_party/blink/public/platform/media/web_media_player_delegate.h"
#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_media_player_client.h"
#include "third_party/blink/public/platform/web_media_player_encrypted_media_client.h"
#include "third_party/blink/public/platform/web_media_player_source.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_surface_layer_bridge.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_testing_support.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/platform/media/buffered_data_source_host_impl.h"
#include "third_party/blink/renderer/platform/media/power_status_helper.h"
#include "third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h"
#include "third_party/blink/renderer/platform/media/testing/mock_resource_fetch_context.h"
#include "third_party/blink/renderer/platform/media/testing/mock_web_associated_url_loader.h"
#include "third_party/blink/renderer/platform/media/video_decode_stats_reporter.h"
#include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
#include "third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "ui/gfx/geometry/size.h"
namespace blink {
namespace {
RunClosure;
RunOnceCallback;
TestAudioConfig;
TestVideoConfig;
_;
AnyNumber;
DoAll;
Eq;
Gt;
InSequence;
Invoke;
NiceMock;
NotNull;
Return;
ReturnRef;
StrictMock;
WithArg;
WithoutArgs;
constexpr char kAudioOnlyTestFile[] = …;
constexpr char kVideoOnlyTestFile[] = …;
constexpr char kVideoAudioTestFile[] = …;
constexpr char kEncryptedVideoOnlyTestFile[] = …;
constexpr base::TimeDelta kAudioOnlyTestFileDuration = …;
enum class BackgroundBehaviorType { … };
MATCHER(WmpiDestroyed, "") { … }
MATCHER_P2(PlaybackRateChanged, old_rate_string, new_rate_string, "") { … }
class MockMediaObserver : public media::MediaObserver { … };
class MockWebMediaPlayerClient : public WebMediaPlayerClient { … };
class MockWebMediaPlayerEncryptedMediaClient
: public WebMediaPlayerEncryptedMediaClient { … };
class MockWebMediaPlayerDelegate : public WebMediaPlayerDelegate { … };
class MockSurfaceLayerBridge : public WebSurfaceLayerBridge { … };
class MockVideoFrameCompositor : public VideoFrameCompositor { … };
}
class WebMediaPlayerImplTest
: public testing::Test,
private WebTestingSupport::WebScopedMockScrollbars { … };
TEST_F(WebMediaPlayerImplTest, ConstructAndDestroy) { … }
TEST_F(WebMediaPlayerImplTest, LoadAndDestroy) { … }
TEST_F(WebMediaPlayerImplTest, LoadAndDestroyDataUrl) { … }
TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspend) { … }
TEST_F(WebMediaPlayerImplTest, NoBufferSizeIncreaseUntilHaveEnough) { … }
TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendNoStreaming) { … }
TEST_F(WebMediaPlayerImplTest, LazyLoadPreloadMetadataSuspend) { … }
TEST_F(WebMediaPlayerImplTest, LazyLoadSkippedForRVFC) { … }
TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendNoVideoMemoryUsage) { … }
TEST_F(WebMediaPlayerImplTest, LoadPreloadMetadataSuspendCouldPlay) { … }
TEST_F(WebMediaPlayerImplTest, IdleSuspendBeforeLoadingBegins) { … }
TEST_F(WebMediaPlayerImplTest,
IdleSuspendIsDisabledIfLoadingProgressedRecently) { … }
TEST_F(WebMediaPlayerImplTest, IdleSuspendIsEnabledIfLoadingHasStalled) { … }
TEST_F(WebMediaPlayerImplTest, DidLoadingProgressTriggersResume) { … }
TEST_F(WebMediaPlayerImplTest, RequestVideoFrameCallback) { … }
TEST_F(WebMediaPlayerImplTest, UpdateFrameIfStale) { … }
TEST_F(WebMediaPlayerImplTest, GetVideoFramePresentationMetadata) { … }
TEST_F(WebMediaPlayerImplTest, OnNewFramePresentedCallback) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Constructed) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_HaveMetadata) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_HaveFutureData) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingError) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Playing) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_PlayingVideoOnly) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Underflow) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHidden) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenAudioOnly) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenVideoOnly) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendNoResume) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameHiddenSuspendWithResume) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_FrameClosed) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_PausedSeek) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Ended) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_DoesNotStaySuspended) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_StaysSuspended) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_ResumeForNeedFirstFrame) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Flinging) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Fullscreen) { … }
TEST_F(WebMediaPlayerImplTest, ComputePlayState_Streaming) { … }
TEST_F(WebMediaPlayerImplTest, IsStreamingIfDemuxerDoesntSupportSeeking) { … }
TEST_F(WebMediaPlayerImplTest, IsNotStreamingIfDemuxerSupportsSeeking) { … }
TEST_F(WebMediaPlayerImplTest, ResumeEnded) { … }
TEST_F(WebMediaPlayerImplTest, AutoplayMuted) { … }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_Playing) { … }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_Paused) { … }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_PositionChange) { … }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_EndOfMedia) { … }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_Underflow) { … }
TEST_F(WebMediaPlayerImplTest, MediaPositionState_InfiniteCurrentTime) { … }
TEST_F(WebMediaPlayerImplTest, NoStreams) { … }
TEST_F(WebMediaPlayerImplTest, Encrypted) { … }
TEST_F(WebMediaPlayerImplTest, Waiting_NoDecryptionKey) { … }
TEST_F(WebMediaPlayerImplTest, Waiting_SecureSurfaceLost) { … }
ACTION(ReportHaveEnough) { … }
ACTION(ReportHardwareContextReset) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(WebMediaPlayerImplTest, FallbackToMediaFoundationRenderer) {
InitializeWebMediaPlayerImpl();
wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto);
auto mock_renderer_factory = std::make_unique<media::MockRendererFactory>();
EXPECT_CALL(*mock_renderer_factory, CreateRenderer(_, _, _, _, _, _))
.WillOnce(testing::WithoutArgs(Invoke([]() {
auto mock_renderer = std::make_unique<NiceMock<media::MockRenderer>>();
EXPECT_CALL(*mock_renderer, OnSetCdm(_, _))
.WillOnce(RunOnceCallback<1>(true));
EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
.WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
WithArg<1>(ReportHaveEnough())));
return mock_renderer;
})));
renderer_factory_selector_->AddFactory(media::RendererType::kMediaFoundation,
std::move(mock_renderer_factory));
EXPECT_CALL(mock_cdm_context_, GetDecryptor())
.WillRepeatedly(Return(nullptr));
EXPECT_CALL(mock_cdm_context_, RequiresMediaFoundationRenderer())
.WillRepeatedly(Return(true));
CreateCdm();
SetCdm();
EXPECT_CALL(encrypted_client_,
Encrypted(media::EmeInitDataType::WEBM, NotNull(), Gt(0u)));
base::RunLoop run_loop;
EXPECT_CALL(client_, DidUseAudioServiceChange(false))
.WillOnce(RunClosure(run_loop.QuitClosure()));
Load(kEncryptedVideoOnlyTestFile);
run_loop.Run();
}
TEST_F(WebMediaPlayerImplTest, PipelineErrorHardwareContextReset) {
InitializeWebMediaPlayerImpl();
wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto);
base::RunLoop run_loop;
auto mock_renderer_factory = std::make_unique<media::MockRendererFactory>();
EXPECT_CALL(*mock_renderer_factory, CreateRenderer(_, _, _, _, _, _))
.WillOnce(testing::WithoutArgs(Invoke([]() {
auto mock_renderer = std::make_unique<NiceMock<media::MockRenderer>>();
EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
.WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
WithArg<1>(ReportHardwareContextReset())));
return mock_renderer;
})))
.WillOnce(testing::WithoutArgs(Invoke([&]() {
auto mock_renderer = std::make_unique<NiceMock<media::MockRenderer>>();
EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
.WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
RunClosure(run_loop.QuitClosure())));
return mock_renderer;
})));
renderer_factory_selector_->AddFactory(media::RendererType::kTest,
std::move(mock_renderer_factory));
renderer_factory_selector_->SetBaseRendererType(media::RendererType::kTest);
Load(kVideoOnlyTestFile);
run_loop.Run();
}
TEST_F(WebMediaPlayerImplTest, PipelineErrorHardwareContextReset_Twice) {
InitializeWebMediaPlayerImpl();
wmpi_->SetPreload(WebMediaPlayer::kPreloadAuto);
base::RunLoop run_loop;
auto mock_renderer_factory = std::make_unique<media::MockRendererFactory>();
EXPECT_CALL(*mock_renderer_factory, CreateRenderer(_, _, _, _, _, _))
.WillOnce(testing::WithoutArgs(Invoke([]() {
auto mock_renderer = std::make_unique<NiceMock<media::MockRenderer>>();
EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
.WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
WithArg<1>(ReportHardwareContextReset())));
return mock_renderer;
})))
.WillOnce(testing::WithoutArgs(Invoke([]() {
auto mock_renderer = std::make_unique<NiceMock<media::MockRenderer>>();
EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
.WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
WithArg<1>(ReportHardwareContextReset())));
return mock_renderer;
})))
.WillOnce(testing::WithoutArgs(Invoke([&]() {
auto mock_renderer = std::make_unique<NiceMock<media::MockRenderer>>();
EXPECT_CALL(*mock_renderer, OnInitialize(_, _, _))
.WillOnce(DoAll(RunOnceCallback<2>(media::PIPELINE_OK),
RunClosure(run_loop.QuitClosure())));
return mock_renderer;
})));
renderer_factory_selector_->AddFactory(media::RendererType::kTest,
std::move(mock_renderer_factory));
renderer_factory_selector_->SetBaseRendererType(media::RendererType::kTest);
Load(kVideoOnlyTestFile);
run_loop.Run();
}
#endif
TEST_F(WebMediaPlayerImplTest, VideoConfigChange) { … }
TEST_F(WebMediaPlayerImplTest, NaturalSizeChange) { … }
TEST_F(WebMediaPlayerImplTest, NaturalSizeChange_Rotated) { … }
TEST_F(WebMediaPlayerImplTest, VideoLockedWhenPausedWhenHidden) { … }
TEST_F(WebMediaPlayerImplTest, NotifiesObserverWhenFrozen) { … }
TEST_F(WebMediaPlayerImplTest, BackgroundIdlePauseTimerDependsOnAudio) { … }
TEST_F(WebMediaPlayerImplTest, InfiniteDuration) { … }
TEST_F(WebMediaPlayerImplTest, SetContentsLayerGetsWebLayerFromBridge) { … }
TEST_F(WebMediaPlayerImplTest, PlaybackRateChangeMediaLogs) { … }
TEST_F(WebMediaPlayerImplTest, PictureInPictureStateChange) { … }
TEST_F(WebMediaPlayerImplTest, OnPictureInPictureStateChangeNotCalled) { … }
TEST_F(WebMediaPlayerImplTest, DisplayTypeChange) { … }
TEST_F(WebMediaPlayerImplTest, RegisterFrameSinkHierarchy) { … }
TEST_F(WebMediaPlayerImplTest, OnProgressClearsStale) { … }
TEST_F(WebMediaPlayerImplTest, MemDumpProvidersRegistration) { … }
TEST_F(WebMediaPlayerImplTest, MemDumpReporting) { … }
TEST_F(WebMediaPlayerImplTest, DISABLED_DemuxerOverride) { … }
class WebMediaPlayerImplBackgroundBehaviorTest
: public WebMediaPlayerImplTest,
public WebAudioSourceProviderClient,
public ::testing::WithParamInterface<
std::tuple<bool, int, int, bool, bool, bool, bool, bool, bool>> { … };
TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, AudioOnly) { … }
TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, VideoOnly) { … }
TEST_P(WebMediaPlayerImplBackgroundBehaviorTest, AudioVideo) { … }
INSTANTIATE_TEST_SUITE_P(…);
}