| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <fuchsia/mem/cpp/fidl.h> |
| |
| #include "base/fuchsia/mem_buffer_util.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/test/test_future.h" |
| #include "base/threading/platform_thread.h" |
| #include "components/cast/message_port/fuchsia/message_port_fuchsia.h" |
| #include "components/cast/message_port/platform_message_port.h" |
| #include "components/cast_streaming/test/cast_streaming_test_sender.h" |
| #include "content/public/test/browser_test.h" |
| #include "fuchsia_web/common/test/fit_adapter.h" |
| #include "fuchsia_web/common/test/frame_for_test.h" |
| #include "fuchsia_web/common/test/frame_test_util.h" |
| #include "fuchsia_web/common/test/test_navigation_listener.h" |
| #include "fuchsia_web/webengine/browser/context_impl.h" |
| #include "fuchsia_web/webengine/browser/frame_impl.h" |
| #include "fuchsia_web/webengine/test/test_data.h" |
| #include "fuchsia_web/webengine/test/web_engine_browser_test.h" |
| #include "media/base/media_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| const char kCastStreamingReceiverPath[] = "/cast_streaming_receiver.html"; |
| |
| media::AudioDecoderConfig GetDefaultAudioConfig() { |
| return media::AudioDecoderConfig( |
| media::AudioCodec::kOpus, media::SampleFormat::kSampleFormatF32, |
| media::ChannelLayout::CHANNEL_LAYOUT_STEREO, |
| 48000 /* samples_per_second */, media::EmptyExtraData(), |
| media::EncryptionScheme::kUnencrypted); |
| } |
| |
| media::VideoDecoderConfig GetDefaultVideoConfig() { |
| const gfx::Size kVideoSize = {1920, 1080}; |
| const gfx::Rect kVideoRect(kVideoSize); |
| |
| return media::VideoDecoderConfig( |
| media::VideoCodec::kVP8, media::VideoCodecProfile::VP8PROFILE_MIN, |
| media::VideoDecoderConfig::AlphaMode::kIsOpaque, media::VideoColorSpace(), |
| media::VideoTransformation(), kVideoSize, kVideoRect, kVideoSize, |
| media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted); |
| } |
| |
| } // namespace |
| |
| // Base test fixture for Cast Streaming tests. |
| class CastStreamingBaseTest : public WebEngineBrowserTest { |
| public: |
| CastStreamingBaseTest() { |
| set_test_server_root(base::FilePath(kTestServerRoot)); |
| } |
| ~CastStreamingBaseTest() override = default; |
| |
| CastStreamingBaseTest(const CastStreamingBaseTest&) = delete; |
| CastStreamingBaseTest& operator=(const CastStreamingBaseTest&) = delete; |
| }; |
| |
| // Test fixture for Cast Streaming tests with the Cast Streaming Receiver flag |
| // disabled. |
| class CastStreamingDisabledTest : public CastStreamingBaseTest { |
| public: |
| CastStreamingDisabledTest() = default; |
| ~CastStreamingDisabledTest() override = default; |
| CastStreamingDisabledTest(const CastStreamingDisabledTest&) = delete; |
| CastStreamingDisabledTest& operator=(const CastStreamingDisabledTest&) = |
| delete; |
| |
| protected: |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| content::BrowserTestBase::SetUpCommandLine(command_line); |
| command_line->RemoveSwitch("enable-cast-streaming-receiver"); |
| } |
| }; |
| |
| // Test fixture for Cast Streaming tests with the Cast Streaming Receiver flag |
| // enabled. |
| class CastStreamingTest : public CastStreamingBaseTest { |
| public: |
| CastStreamingTest() = default; |
| ~CastStreamingTest() override = default; |
| CastStreamingTest(const CastStreamingTest&) = delete; |
| CastStreamingTest& operator=(const CastStreamingTest&) = delete; |
| |
| protected: |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| content::BrowserTestBase::SetUpCommandLine(command_line); |
| command_line->AppendSwitch("enable-cast-streaming-receiver"); |
| } |
| }; |
| |
| // Check that attempting to load the cast streaming media source URL when the |
| // command line switch is not set fails as expected. |
| IN_PROC_BROWSER_TEST_F(CastStreamingDisabledTest, LoadFailure) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| const GURL page_url( |
| embedded_test_server()->GetURL(kCastStreamingReceiverPath)); |
| |
| auto frame = |
| FrameForTest::Create(context(), fuchsia::web::CreateFrameParams()); |
| EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(), |
| fuchsia::web::LoadUrlParams(), |
| page_url.spec())); |
| frame.navigation_listener().RunUntilTitleEquals("error"); |
| } |
| |
| // Check that attempting to load the cast streaming media source URL when the |
| // command line switch is set properly succeeds. |
| IN_PROC_BROWSER_TEST_F(CastStreamingTest, LoadSuccess) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| const GURL page_url( |
| embedded_test_server()->GetURL(kCastStreamingReceiverPath)); |
| fuchsia::mem::Buffer ignored_message_string = |
| base::MemBufferFromString("hi", "test"); |
| |
| std::unique_ptr<cast_api_bindings::MessagePort> sender_message_port; |
| std::unique_ptr<cast_api_bindings::MessagePort> receiver_message_port; |
| cast_api_bindings::CreatePlatformMessagePortPair(&sender_message_port, |
| &receiver_message_port); |
| |
| fidl::InterfaceRequest<::fuchsia::web::MessagePort> message_port_request = |
| cast_api_bindings::MessagePortFuchsia::FromMessagePort( |
| receiver_message_port.get()) |
| ->TakeServiceRequest(); |
| |
| // Start the Sender |
| cast_streaming::CastStreamingTestSender sender; |
| sender.Start(std::move(sender_message_port), net::IPAddress::IPv6Localhost(), |
| GetDefaultAudioConfig(), GetDefaultVideoConfig()); |
| |
| // Create a Frame and set the Receiver MessagePort on it. |
| auto frame = |
| FrameForTest::Create(context(), fuchsia::web::CreateFrameParams()); |
| base::test::TestFuture<fuchsia::web::Frame_PostMessage_Result> post_result; |
| frame->PostMessage( |
| "cast-streaming:receiver", |
| CreateWebMessageWithMessagePortRequest(std::move(message_port_request), |
| std::move(ignored_message_string)), |
| CallbackToFitFunction(post_result.GetCallback())); |
| EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(), |
| fuchsia::web::LoadUrlParams(), |
| page_url.spec())); |
| |
| ASSERT_TRUE(sender.RunUntilActive()); |
| frame.navigation_listener().RunUntilTitleEquals("loadedmetadata"); |
| |
| EXPECT_TRUE(post_result.Wait()); |
| EXPECT_NE(sender.audio_decoder_config(), absl::nullopt); |
| EXPECT_NE(sender.video_decoder_config(), absl::nullopt); |
| } |
| |
| // Check that attempting to start a video-only receiver properly disables audio. |
| IN_PROC_BROWSER_TEST_F(CastStreamingTest, VideoOnlyReceiver) { |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| const GURL kPageUrl( |
| embedded_test_server()->GetURL(kCastStreamingReceiverPath)); |
| fuchsia::mem::Buffer ignored_message_string = |
| base::MemBufferFromString("hi", "test"); |
| |
| std::unique_ptr<cast_api_bindings::MessagePort> sender_message_port; |
| std::unique_ptr<cast_api_bindings::MessagePort> receiver_message_port; |
| cast_api_bindings::CreatePlatformMessagePortPair(&sender_message_port, |
| &receiver_message_port); |
| |
| fidl::InterfaceRequest<::fuchsia::web::MessagePort> message_port_request = |
| cast_api_bindings::MessagePortFuchsia::FromMessagePort( |
| receiver_message_port.get()) |
| ->TakeServiceRequest(); |
| |
| // Start the Sender |
| cast_streaming::CastStreamingTestSender sender; |
| sender.Start(std::move(sender_message_port), net::IPAddress::IPv6Localhost(), |
| GetDefaultAudioConfig(), GetDefaultVideoConfig()); |
| |
| // Create a Frame and set the Receiver MessagePort on it. |
| auto frame = |
| FrameForTest::Create(context(), fuchsia::web::CreateFrameParams()); |
| base::test::TestFuture<fuchsia::web::Frame_PostMessage_Result> post_result; |
| frame->PostMessage( |
| "cast-streaming:video-only-receiver", |
| CreateWebMessageWithMessagePortRequest(std::move(message_port_request), |
| std::move(ignored_message_string)), |
| CallbackToFitFunction(post_result.GetCallback())); |
| |
| EXPECT_TRUE(LoadUrlAndExpectResponse(frame.GetNavigationController(), |
| fuchsia::web::LoadUrlParams(), |
| kPageUrl.spec())); |
| |
| ASSERT_TRUE(sender.RunUntilActive()); |
| frame.navigation_listener().RunUntilTitleEquals("loadedmetadata"); |
| |
| EXPECT_TRUE(post_result.Wait()); |
| EXPECT_EQ(sender.audio_decoder_config(), absl::nullopt); |
| EXPECT_NE(sender.video_decoder_config(), absl::nullopt); |
| } |