#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include <array>
#include <optional>
#include <queue>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_pump.h"
#include "base/task/sequence_manager/task_queue.h"
#include "base/task/sequence_manager/thread_controller_power_monitor.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_features.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
_;
Invoke;
ElementsAre;
namespace base::sequence_manager::internal {
namespace {
class ThreadControllerForTest : public ThreadControllerWithMessagePumpImpl { … };
class MockMessagePump : public MessagePump { … };
class FakeTaskRunner : public SingleThreadTaskRunner { … };
class FakeSequencedTaskSource : public SequencedTaskSource { … };
}
class ThreadControllerWithMessagePumpTestBase : public testing::Test { … };
class ThreadControllerWithMessagePumpTest
: public ThreadControllerWithMessagePumpTestBase { … };
class ThreadControllerWithMessagePumpNoBatchesTest
: public ThreadControllerWithMessagePumpTestBase { … };
TEST_F(ThreadControllerWithMessagePumpTest, ScheduleDelayedWork) { … }
TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork) { … }
TEST_F(ThreadControllerWithMessagePumpTest, SetNextDelayedDoWork_CapAtOneDay) { … }
TEST_F(ThreadControllerWithMessagePumpTest, DelayedWork_CapAtOneDay) { … }
TEST_F(ThreadControllerWithMessagePumpTest, DoWorkDoesntScheduleDelayedWork) { … }
TEST_F(ThreadControllerWithMessagePumpTest, NestedExecution) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
NestedExecutionWithApplicationTasks) { … }
TEST_F(ThreadControllerWithMessagePumpTest, SetDefaultTaskRunner) { … }
TEST_F(ThreadControllerWithMessagePumpTest, EnsureWorkScheduled) { … }
TEST_F(ThreadControllerWithMessagePumpTest, WorkBatching) { … }
TEST_F(ThreadControllerWithMessagePumpTest, QuitInterruptsBatch) { … }
TEST_F(ThreadControllerWithMessagePumpTest, PrioritizeYieldingToNative) { … }
TEST_F(ThreadControllerWithMessagePumpTest, EarlyQuit) { … }
TEST_F(ThreadControllerWithMessagePumpTest, NativeNestedMessageLoop) { … }
TEST_F(ThreadControllerWithMessagePumpTest, RunWithTimeout) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(ThreadControllerWithMessagePumpTest, SetHighResolutionTimer) {
MockCallback<OnceClosure> task;
task_source_.AddTask(FROM_HERE, task.Get(), FromNow(Seconds(5)),
clock_.NowTicks());
SingleThreadTaskRunner::CurrentDefaultHandle handle(
MakeRefCounted<FakeTaskRunner>());
EXPECT_CALL(*message_pump_, Run(_))
.WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
EXPECT_FALSE(
thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
task_source_.SetHasPendingHighResolutionTasks(true);
delegate->DoIdleWork();
EXPECT_TRUE(
thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
task_source_.SetHasPendingHighResolutionTasks(false);
delegate->DoIdleWork();
EXPECT_FALSE(
thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
EXPECT_CALL(*message_pump_, Quit());
thread_controller_.Quit();
}));
RunLoop run_loop;
run_loop.Run();
}
#endif
#if BUILDFLAG(IS_WIN)
TEST_F(ThreadControllerWithMessagePumpTest,
SetHighResolutionTimerWithPowerSuspend) {
MockCallback<OnceClosure> task;
task_source_.AddTask(FROM_HERE, task.Get(), FromNow(Seconds(5)),
clock_.NowTicks());
SingleThreadTaskRunner::CurrentDefaultHandle handle(
MakeRefCounted<FakeTaskRunner>());
EXPECT_CALL(*message_pump_, Run(_))
.WillOnce(Invoke([&](MessagePump::Delegate* delegate) {
EXPECT_FALSE(
thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
thread_controller_.ThreadControllerPowerMonitorForTesting()
->OnSuspend();
task_source_.SetHasPendingHighResolutionTasks(true);
delegate->DoIdleWork();
EXPECT_FALSE(
thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
thread_controller_.ThreadControllerPowerMonitorForTesting()->OnResume();
delegate->DoIdleWork();
EXPECT_TRUE(
thread_controller_.MainThreadOnlyForTesting().in_high_res_mode);
EXPECT_CALL(*message_pump_, Quit());
thread_controller_.Quit();
}));
RunLoop run_loop;
run_loop.Run();
}
#endif
TEST_F(ThreadControllerWithMessagePumpTest,
ScheduleDelayedWorkWithPowerSuspend) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveSingleApplicationTask) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveMultipleApplicationTasks) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveWakeUpForNothing) { … }
TEST_F(ThreadControllerWithMessagePumpTest, DoWorkBatches) { … }
TEST_F(ThreadControllerWithMessagePumpNoBatchesTest, DoWorkBatches) { … }
TEST_F(ThreadControllerWithMessagePumpTest, DoWorkBatchesForSetTime) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveAdvancedNesting) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveNestedNativeLoop) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveUnusedNativeLoop) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveNestedNativeLoopWithoutAllowance) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveMultipleNativeLoopsUnderOneApplicationTask) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveNativeLoopsReachingIdle) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveQuitNestedWhileApplicationIdle) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveNestedWithinNativeAllowsApplicationTasks) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
ThreadControllerActiveDummyScopedAllowApplicationTasks) { … }
TEST_F(ThreadControllerWithMessagePumpTest, MessagePumpPhasesWithQueuingTime) { … }
TEST_F(ThreadControllerWithMessagePumpNoBatchesTest,
WorkIdIncrementedForEveryWorkItem) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
WorkIdIncrementedForEveryWorkItemInBatches) { … }
TEST_F(ThreadControllerWithMessagePumpTest, WorkIdIncrementedForIdleWork) { … }
TEST_F(ThreadControllerWithMessagePumpTest, WorkIdIncrementedScopedDoWorkItem) { … }
TEST_F(ThreadControllerWithMessagePumpTest,
WorkIdIncrementedDelegateBeforeWait) { … }
TEST_F(ThreadControllerWithMessagePumpTest, WorkIdIncrementedDelegateRun) { … }
}