#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include <memory>
#include <tuple>
#include "base/feature_list.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/v8_cache_options.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/bindings/core/v8/module_record.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/worker_devtools_params.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
#include "third_party/blink/renderer/core/script/js_module_script.h"
#include "third_party/blink/renderer/core/script/script.h"
#include "third_party/blink/renderer/core/testing/module_test_base.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread.h"
#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/core/workers/worklet_module_responses_map.h"
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h"
#include "third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h"
#include "third_party/blink/renderer/modules/webaudio/offline_audio_worklet_thread.h"
#include "third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.h"
#include "third_party/blink/renderer/modules/webaudio/semi_realtime_audio_worklet_thread.h"
#include "third_party/blink/renderer/platform/bindings/source_location.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/text/text_position.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
namespace blink {
class AudioWorkletThreadTest : public PageTestBase, public ModuleTestBase { … };
TEST_F(AudioWorkletThreadTest, Basic) { … }
TEST_F(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_1) { … }
TEST_F(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_2) { … }
class AudioWorkletThreadInteractionTest
: public AudioWorkletThreadTest,
public testing::WithParamInterface<std::tuple<bool, bool>> { … };
TEST_P(AudioWorkletThreadInteractionTest, CreateSecondAndTerminateFirst) { … }
TEST_P(AudioWorkletThreadInteractionTest, TerminateFirstAndCreateSecond) { … }
TEST_P(AudioWorkletThreadInteractionTest,
ThreadManagementSystemForRealtimeAndTopLevelFrame) { … }
INSTANTIATE_TEST_SUITE_P(…);
struct ThreadPriorityTestParam { … };
constexpr ThreadPriorityTestParam kThreadPriorityTestParams[] = …;
class AudioWorkletThreadPriorityTest
: public AudioWorkletThreadTest,
public testing::WithParamInterface<ThreadPriorityTestParam> { … };
TEST_P(AudioWorkletThreadPriorityTest, CheckThreadPriority) { … }
INSTANTIATE_TEST_SUITE_P(…);
}
#if BUILDFLAG(IS_APPLE)
namespace WTF {
template <>
struct CrossThreadCopier<base::TimeDelta>
: public CrossThreadCopierPassThrough<base::TimeDelta> {
STATIC_ONLY(CrossThreadCopier);
};
}
namespace blink {
class AudioWorkletRealtimePeriodTestMac : public AudioWorkletThreadTest {
public:
std::unique_ptr<WorkerThread> CreateThreadAndCheckRealtimePeriod(
base::TimeDelta realtime_buffer_duration,
base::TimeDelta expected_realtime_period) {
std::unique_ptr<WorkerThread> audio_worklet_thread =
CreateAudioWorkletThread(true,
true,
realtime_buffer_duration);
WorkerThread* thread = audio_worklet_thread.get();
base::WaitableEvent wait_event;
PostCrossThreadTask(
*thread->GetWorkerBackingThread().BackingThread().GetTaskRunner(),
FROM_HERE,
CrossThreadBindOnce(
&AudioWorkletRealtimePeriodTestMac::
CheckThreadRealtimePeriodOnWorkerThread,
CrossThreadUnretained(this), CrossThreadUnretained(thread),
expected_realtime_period, CrossThreadUnretained(&wait_event)));
wait_event.Wait();
return audio_worklet_thread;
}
private:
void CheckThreadRealtimePeriodOnWorkerThread(
WorkerThread* thread,
base::TimeDelta expected_realtime_period,
base::WaitableEvent* wait_event) {
ASSERT_TRUE(thread->IsCurrentThread());
base::ThreadPriorityForTest actual_priority =
base::PlatformThread::GetCurrentThreadPriorityForTest();
base::TimeDelta actual_realtime_period =
base::PlatformThread::GetCurrentThreadRealtimePeriodForTest();
EXPECT_EQ(actual_priority, base::ThreadPriorityForTest::kRealtimeAudio);
EXPECT_EQ(actual_realtime_period, expected_realtime_period);
wait_event->Signal();
}
};
TEST_F(AudioWorkletRealtimePeriodTestMac, CheckRealtimePeriod) {
base::TimeDelta realtime_buffer_durations[] = {
base::Milliseconds(10), base::Milliseconds(20), base::Milliseconds(30),
base::Milliseconds(40), base::Milliseconds(50)};
std::vector<std::unique_ptr<WorkerThread>> worklet_threads;
worklet_threads.push_back(CreateThreadAndCheckRealtimePeriod(
realtime_buffer_durations[0], realtime_buffer_durations[0]));
worklet_threads.push_back(CreateThreadAndCheckRealtimePeriod(
realtime_buffer_durations[1], realtime_buffer_durations[1]));
worklet_threads.push_back(CreateThreadAndCheckRealtimePeriod(
realtime_buffer_durations[2], realtime_buffer_durations[2]));
worklet_threads.push_back(CreateThreadAndCheckRealtimePeriod(
realtime_buffer_durations[3], realtime_buffer_durations[3]));
worklet_threads.push_back(CreateThreadAndCheckRealtimePeriod(
realtime_buffer_durations[4], realtime_buffer_durations[3]));
for (auto& worklet_thread : worklet_threads) {
if (worklet_thread.get()) {
worklet_thread->Terminate();
worklet_thread->WaitForShutdownForTesting();
}
}
}
}
#endif