// Copyright (c) 2018 The Chromium Embedded Framework 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 "include/base/cef_bind.h" #include "include/wrapper/cef_closure_task.h" #include "tests/ceftests/test_handler.h" #include "tests/gtest/include/gtest/gtest.h" #include "tests/shared/browser/client_app_browser.h" using client::ClientAppBrowser; namespace { const int kNumChannels = 2; const CefAudioHandler::ChannelLayout kChannelLayout = CEF_CHANNEL_LAYOUT_STEREO; const char kTestUrl[] = "http://tests/audiooutputtest"; // Taken from: // http://www.iandevlin.com/blog/2012/09/html5/html5-media-and-data-uri/ const char kTestHtml[] = "

TEST

"; class AudioOutputTest : public ClientAppBrowser::Delegate { public: AudioOutputTest() {} void OnBeforeCommandLineProcessing( CefRefPtr app, CefRefPtr command_line) override { // Allow media to autoplay without requiring user interaction. command_line->AppendSwitchWithValue("autoplay-policy", "no-user-gesture-required"); } protected: IMPLEMENT_REFCOUNTING(AudioOutputTest); }; // a common base class for audio output tests class AudioOutputTestHandler : public TestHandler, public CefAudioHandler { public: AudioOutputTestHandler() : audio_stream_id_(-1), frames_per_buffer_(-1) {} void RunTest() override { // Add the resource AddResource(kTestUrl, kTestHtml, "text/html"); // Create the browser. CreateBrowser(kTestUrl); // Time out the test after a reasonable period of time. SetTestTimeout(); } CefRefPtr GetAudioHandler() override { return this; } void OnAudioStreamStarted(CefRefPtr browser, int audio_stream_id, int channels, ChannelLayout channel_layout, int sample_rate, int frames_per_buffer) override { EXPECT_FALSE(got_on_audio_stream_started_); EXPECT_TRUE(GetBrowser()->IsSame(browser)); EXPECT_TRUE(CefCurrentlyOn(TID_UI)); EXPECT_EQ(channels, kNumChannels); EXPECT_EQ(channel_layout, kChannelLayout); EXPECT_GE(sample_rate, 22050); EXPECT_LE(sample_rate, 48000); EXPECT_GE(frames_per_buffer, 441); EXPECT_LE(frames_per_buffer, 1280); audio_stream_id_ = audio_stream_id; frames_per_buffer_ = frames_per_buffer; got_on_audio_stream_started_.yes(); } void OnAudioStreamPacket(CefRefPtr browser, int audio_stream_id, const float** data, int frames, int64 pts) override { if (!got_on_audio_stream_packet_.isSet()) { EXPECT_TRUE(got_on_audio_stream_started_); EXPECT_EQ(audio_stream_id_, audio_stream_id); EXPECT_TRUE(CefCurrentlyOn(TID_UI)); EXPECT_EQ(frames, frames_per_buffer_); browser->GetMainFrame()->ExecuteJavaScript( "var ifr = document.getElementById(\"audio_output_frame\"); " "ifr.parentNode.removeChild(ifr);", CefString(), 0); got_on_audio_stream_packet_.yes(); } } void OnAudioStreamStopped(CefRefPtr browser, int audio_stream_id) override { EXPECT_FALSE(got_on_audio_stream_stopped_); EXPECT_TRUE(got_on_audio_stream_started_); EXPECT_EQ(audio_stream_id_, audio_stream_id); EXPECT_TRUE(CefCurrentlyOn(TID_UI)); got_on_audio_stream_stopped_.yes(); DestroyTest(); } protected: void DestroyTest() override { EXPECT_TRUE(got_on_audio_stream_started_); EXPECT_TRUE(got_on_audio_stream_packet_); EXPECT_TRUE(got_on_audio_stream_stopped_); TestHandler::DestroyTest(); } int audio_stream_id_; int frames_per_buffer_; TrackCallback got_on_audio_stream_started_; TrackCallback got_on_audio_stream_packet_; TrackCallback got_on_audio_stream_stopped_; IMPLEMENT_REFCOUNTING(AudioOutputTestHandler); }; } // namespace // Test audio output callbacks called on valid threads TEST(AudioOutputTest, AudioOutputTest) { CefRefPtr handler = new AudioOutputTestHandler(); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } // Entry point for creating audio output test objects. // Called from client_app_delegates.cc. void CreateAudioOutputTests(ClientAppBrowser::DelegateSet& delegates) { delegates.insert(new AudioOutputTest); }