alive_checker_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/memory/raw_ptr.h"
  8. #include "base/synchronization/waitable_event.h"
  9. #include "base/task/sequenced_task_runner.h"
  10. #include "base/test/task_environment.h"
  11. #include "base/threading/thread.h"
  12. #include "base/time/time.h"
  13. #include "media/audio/alive_checker.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. namespace media {
  16. namespace {
  17. int kCheckIntervalMs = 10;
  18. int kTimeoutMs = 50;
  19. } // namespace
  20. class MockPowerObserverHelper : public PowerObserverHelper {
  21. public:
  22. MockPowerObserverHelper(scoped_refptr<base::SequencedTaskRunner> task_runner,
  23. base::RepeatingClosure suspend_callback,
  24. base::RepeatingClosure resume_callback)
  25. : PowerObserverHelper(std::move(task_runner),
  26. std::move(suspend_callback),
  27. std::move(resume_callback)) {}
  28. bool IsSuspending() const override {
  29. DCHECK(TaskRunnerForTesting()->RunsTasksInCurrentSequence());
  30. return is_suspending_;
  31. }
  32. void Suspend() {
  33. DCHECK(TaskRunnerForTesting()->RunsTasksInCurrentSequence());
  34. is_suspending_ = true;
  35. SuspendCallbackForTesting()->Run();
  36. }
  37. void Resume() {
  38. DCHECK(TaskRunnerForTesting()->RunsTasksInCurrentSequence());
  39. is_suspending_ = false;
  40. ResumeCallbackForTesting()->Run();
  41. }
  42. private:
  43. bool is_suspending_ = false;
  44. };
  45. class AliveCheckerTest : public testing::Test {
  46. public:
  47. AliveCheckerTest()
  48. : alive_checker_thread_("AliveCheckerThread"),
  49. detected_dead_event_(base::WaitableEvent::ResetPolicy::MANUAL,
  50. base::WaitableEvent::InitialState::NOT_SIGNALED) {
  51. alive_checker_thread_.StartAndWaitForTesting();
  52. }
  53. AliveCheckerTest(const AliveCheckerTest&) = delete;
  54. AliveCheckerTest& operator=(const AliveCheckerTest&) = delete;
  55. void OnDetectedDead() {
  56. EXPECT_TRUE(alive_checker_thread_.task_runner()->BelongsToCurrentThread());
  57. detected_dead_event_.Signal();
  58. }
  59. std::unique_ptr<PowerObserverHelper> CreatePowerObserverHelper(
  60. scoped_refptr<base::SequencedTaskRunner> task_runner,
  61. base::RepeatingClosure suspend_callback,
  62. base::RepeatingClosure resume_callback) {
  63. std::unique_ptr<MockPowerObserverHelper> mock_power_observer_helper =
  64. std::make_unique<MockPowerObserverHelper>(std::move(task_runner),
  65. std::move(suspend_callback),
  66. std::move(resume_callback));
  67. mock_power_observer_helper_ = mock_power_observer_helper.get();
  68. return mock_power_observer_helper;
  69. }
  70. protected:
  71. ~AliveCheckerTest() override {
  72. base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
  73. base::WaitableEvent::InitialState::NOT_SIGNALED);
  74. alive_checker_thread_.task_runner()->PostTask(
  75. FROM_HERE,
  76. base::BindOnce(&AliveCheckerTest::ResetAliveCheckerOnAliveCheckerThread,
  77. base::Unretained(this), &done));
  78. done.Wait();
  79. }
  80. void CreateAliveChecker(bool stop_at_first_alive_notification,
  81. bool pause_check_during_suspend) {
  82. base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
  83. base::WaitableEvent::InitialState::NOT_SIGNALED);
  84. alive_checker_thread_.task_runner()->PostTask(
  85. FROM_HERE,
  86. base::BindOnce(
  87. &AliveCheckerTest::CreateAliveCheckerOnAliveCheckerThread,
  88. base::Unretained(this), stop_at_first_alive_notification,
  89. pause_check_during_suspend, &done));
  90. done.Wait();
  91. }
  92. void StartAliveChecker() {
  93. alive_checker_thread_.task_runner()->PostTask(
  94. FROM_HERE, base::BindOnce(&AliveChecker::Start,
  95. base::Unretained(alive_checker_.get())));
  96. }
  97. void StopAliveChecker() {
  98. alive_checker_thread_.task_runner()->PostTask(
  99. FROM_HERE, base::BindOnce(&AliveChecker::Stop,
  100. base::Unretained(alive_checker_.get())));
  101. }
  102. // Notifies |alive_checker_| that we're alive, and if
  103. // |remaining_notifications| > 1, posts a delayed task to itself on
  104. // |alive_checker_thread_| with |remaining_notifications| decreased by 1. Can
  105. // be called on any task runner.
  106. void NotifyAliveMultipleTimes(int remaining_notifications,
  107. base::TimeDelta delay) {
  108. alive_checker_->NotifyAlive();
  109. if (remaining_notifications > 1) {
  110. alive_checker_thread_.task_runner()->PostDelayedTask(
  111. FROM_HERE,
  112. base::BindOnce(&AliveCheckerTest::NotifyAliveMultipleTimes,
  113. base::Unretained(this), remaining_notifications - 1,
  114. delay),
  115. delay);
  116. }
  117. }
  118. void WaitUntilDetectedDead() {
  119. detected_dead_event_.Wait();
  120. detected_dead_event_.Reset();
  121. }
  122. // Returns true if the dead callback (AliveCheckerTest::OnDetectedDead) is run
  123. // by the AliveChecker, false if timed out.
  124. bool WaitUntilDetectedDeadWithTimeout(base::TimeDelta timeout) {
  125. bool signaled = detected_dead_event_.TimedWait(timeout);
  126. detected_dead_event_.Reset();
  127. return signaled;
  128. }
  129. // Calls AliveChecker::DetectedDead() on the |alive_checker_thread_| and
  130. // returns the result.
  131. bool GetDetectedDead() {
  132. bool detected_dead = false;
  133. base::WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL,
  134. base::WaitableEvent::InitialState::NOT_SIGNALED);
  135. alive_checker_thread_.task_runner()->PostTask(
  136. FROM_HERE,
  137. base::BindOnce(&AliveCheckerTest::GetDetectedDeadOnAliveCheckerThread,
  138. base::Unretained(this), &detected_dead, &done));
  139. done.Wait();
  140. return detected_dead;
  141. }
  142. // The test task environment.
  143. base::test::TaskEnvironment task_environment_;
  144. // The thread the checker is run on.
  145. base::Thread alive_checker_thread_;
  146. // AliveChecker under test.
  147. std::unique_ptr<AliveChecker> alive_checker_;
  148. // Mocks suspend status. Set in CreatePowerObserverHelper, owned by
  149. // |alive_checker_|.
  150. raw_ptr<MockPowerObserverHelper> mock_power_observer_helper_;
  151. private:
  152. void CreateAliveCheckerOnAliveCheckerThread(
  153. bool stop_at_first_alive_notification,
  154. bool pause_check_during_suspend,
  155. base::WaitableEvent* done) {
  156. EXPECT_TRUE(alive_checker_thread_.task_runner()->BelongsToCurrentThread());
  157. if (pause_check_during_suspend) {
  158. alive_checker_ = std::make_unique<AliveChecker>(
  159. base::BindRepeating(&AliveCheckerTest::OnDetectedDead,
  160. base::Unretained(this)),
  161. base::Milliseconds(kCheckIntervalMs), base::Milliseconds(kTimeoutMs),
  162. stop_at_first_alive_notification,
  163. base::BindOnce(&AliveCheckerTest::CreatePowerObserverHelper,
  164. base::Unretained(this)));
  165. } else {
  166. alive_checker_ = std::make_unique<AliveChecker>(
  167. base::BindRepeating(&AliveCheckerTest::OnDetectedDead,
  168. base::Unretained(this)),
  169. base::Milliseconds(kCheckIntervalMs), base::Milliseconds(kTimeoutMs),
  170. stop_at_first_alive_notification, false);
  171. }
  172. done->Signal();
  173. }
  174. void GetDetectedDeadOnAliveCheckerThread(bool* detected_dead,
  175. base::WaitableEvent* done) {
  176. EXPECT_TRUE(alive_checker_thread_.task_runner()->BelongsToCurrentThread());
  177. *detected_dead = alive_checker_->DetectedDead();
  178. done->Signal();
  179. }
  180. void ResetAliveCheckerOnAliveCheckerThread(base::WaitableEvent* done) {
  181. EXPECT_TRUE(alive_checker_thread_.task_runner()->BelongsToCurrentThread());
  182. alive_checker_.reset();
  183. done->Signal();
  184. }
  185. // Event to signal that we got a dead detection callback.
  186. base::WaitableEvent detected_dead_event_;
  187. };
  188. // Start the checker, don't send alive notifications, and run until it detects
  189. // dead. Verify that it only detects once. Repeat once.
  190. TEST_F(AliveCheckerTest, NoAliveNotificationsDetectTwice) {
  191. CreateAliveChecker(false, false);
  192. StartAliveChecker();
  193. EXPECT_FALSE(GetDetectedDead());
  194. WaitUntilDetectedDead();
  195. EXPECT_TRUE(GetDetectedDead());
  196. // Verify that AliveChecker doesn't detect (runs the callback) a second time.
  197. // It can take up to the timeout + the check interval until detection. Add a
  198. // margin to this. The detect state should still be that we have detected
  199. // dead.
  200. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  201. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  202. EXPECT_TRUE(GetDetectedDead());
  203. // Start again, the detect state should be reset.
  204. StartAliveChecker();
  205. EXPECT_FALSE(GetDetectedDead());
  206. WaitUntilDetectedDead();
  207. EXPECT_TRUE(GetDetectedDead());
  208. }
  209. // Setup the checker to stop at first alive notification. Start it and notify
  210. // that the client is alive once. Verify that we get no dead detection.
  211. TEST_F(AliveCheckerTest, StopAtFirstAliveNotification_DoNotify) {
  212. CreateAliveChecker(true, false);
  213. StartAliveChecker();
  214. alive_checker_->NotifyAlive();
  215. // It can take up to the timeout + the check interval until detection. Add a
  216. // margin to this.
  217. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  218. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  219. EXPECT_FALSE(GetDetectedDead());
  220. }
  221. // Setup the checker to stop at first alive notification. Start it and run until
  222. // it detects dead.
  223. TEST_F(AliveCheckerTest, StopAtFirstAliveNotification_DontNotify) {
  224. CreateAliveChecker(true, false);
  225. StartAliveChecker();
  226. WaitUntilDetectedDead();
  227. EXPECT_TRUE(GetDetectedDead());
  228. }
  229. // Setup the checker to pause checking when suspended. Suspend and verify that
  230. // it doesn't detect dead. Start the checker, don't send alive notifications,
  231. // and and verify that it doesn't detect dead. Resume and run until it detects
  232. // dead.
  233. TEST_F(AliveCheckerTest, SuspendResume_StartBetweenSuspendAndResume) {
  234. CreateAliveChecker(false, true);
  235. ASSERT_TRUE(mock_power_observer_helper_);
  236. alive_checker_thread_.task_runner()->PostTask(
  237. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Suspend,
  238. base::Unretained(mock_power_observer_helper_)));
  239. StartAliveChecker();
  240. // It can take up to the timeout + the check interval until detection. Add a
  241. // margin to this.
  242. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  243. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  244. EXPECT_FALSE(GetDetectedDead());
  245. alive_checker_thread_.task_runner()->PostTask(
  246. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Resume,
  247. base::Unretained(mock_power_observer_helper_)));
  248. WaitUntilDetectedDead();
  249. EXPECT_TRUE(GetDetectedDead());
  250. }
  251. // Setup the checker to stop at first alive notification and pause checking when
  252. // suspended. Start the checker, send one alive notifications, and verify it
  253. // doesn't detect dead. Suspend and verify that it doesn't detect dead. Resume
  254. // and and verify that it doesn't detect dead.
  255. TEST_F(AliveCheckerTest, SuspendResumeWithAutoStop_NotifyBeforeSuspend) {
  256. CreateAliveChecker(true, true);
  257. ASSERT_TRUE(mock_power_observer_helper_);
  258. StartAliveChecker();
  259. alive_checker_->NotifyAlive();
  260. // It can take up to the timeout + the check interval until detection. Add a
  261. // margin to this.
  262. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  263. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  264. EXPECT_FALSE(GetDetectedDead());
  265. alive_checker_thread_.task_runner()->PostTask(
  266. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Suspend,
  267. base::Unretained(mock_power_observer_helper_)));
  268. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  269. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  270. EXPECT_FALSE(GetDetectedDead());
  271. alive_checker_thread_.task_runner()->PostTask(
  272. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Resume,
  273. base::Unretained(mock_power_observer_helper_)));
  274. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  275. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  276. EXPECT_FALSE(GetDetectedDead());
  277. }
  278. // Setup the checker to stop at first alive notification and pause checking when
  279. // suspended. Start the checker, send one alive notifications, and verify it
  280. // doesn't detect dead. Start it again, suspend and verify that it doesn't
  281. // detect dead. Resume and run until detected dead.
  282. TEST_F(AliveCheckerTest,
  283. SuspendResumeWithAutoStop_NotifyBeforeSuspendAndRestart) {
  284. CreateAliveChecker(true, true);
  285. ASSERT_TRUE(mock_power_observer_helper_);
  286. StartAliveChecker();
  287. alive_checker_->NotifyAlive();
  288. // It can take up to the timeout + the check interval until detection. Add a
  289. // margin to this.
  290. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  291. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  292. EXPECT_FALSE(GetDetectedDead());
  293. StartAliveChecker();
  294. EXPECT_FALSE(GetDetectedDead());
  295. alive_checker_thread_.task_runner()->PostTask(
  296. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Suspend,
  297. base::Unretained(mock_power_observer_helper_)));
  298. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  299. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  300. EXPECT_FALSE(GetDetectedDead());
  301. alive_checker_thread_.task_runner()->PostTask(
  302. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Resume,
  303. base::Unretained(mock_power_observer_helper_)));
  304. WaitUntilDetectedDead();
  305. EXPECT_TRUE(GetDetectedDead());
  306. }
  307. // Setup the checker to stop at first alive notification and pause checking when
  308. // suspended. Start the checker, suspend. Send one alive notification and
  309. // verify it doesn't detected dead. Resume and verify it doesn't detected dead.
  310. TEST_F(AliveCheckerTest,
  311. SuspendResumeWithAutoStop_NotifyBetweenSuspendAndResume) {
  312. CreateAliveChecker(true, true);
  313. ASSERT_TRUE(mock_power_observer_helper_);
  314. StartAliveChecker();
  315. alive_checker_thread_.task_runner()->PostTask(
  316. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Suspend,
  317. base::Unretained(mock_power_observer_helper_)));
  318. alive_checker_->NotifyAlive();
  319. // It can take up to the timeout + the check interval until detection. Add a
  320. // margin to this.
  321. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  322. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  323. EXPECT_FALSE(GetDetectedDead());
  324. alive_checker_thread_.task_runner()->PostTask(
  325. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Resume,
  326. base::Unretained(mock_power_observer_helper_)));
  327. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  328. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  329. EXPECT_FALSE(GetDetectedDead());
  330. }
  331. // Setup the checker to stop at first alive notification and pause checking when
  332. // suspended. Start the checker, suspend, resume, send one alive notification
  333. // and verify it doesn't detected dead.
  334. TEST_F(AliveCheckerTest, SuspendResumeWithAutoStop_NotifyAfterResume) {
  335. CreateAliveChecker(true, true);
  336. ASSERT_TRUE(mock_power_observer_helper_);
  337. StartAliveChecker();
  338. alive_checker_thread_.task_runner()->PostTask(
  339. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Suspend,
  340. base::Unretained(mock_power_observer_helper_)));
  341. alive_checker_thread_.task_runner()->PostTask(
  342. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Resume,
  343. base::Unretained(mock_power_observer_helper_)));
  344. alive_checker_->NotifyAlive();
  345. // It can take up to the timeout + the check interval until detection. Add a
  346. // margin to this.
  347. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  348. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  349. EXPECT_FALSE(GetDetectedDead());
  350. }
  351. // Setup the checker to stop at first alive notification and pause checking when
  352. // suspended. Start the checker suspend, and and verify it doesn't detected
  353. // dead. Resume and run until it detects dead.
  354. TEST_F(AliveCheckerTest, SuspendResumeWithAutoStop_DontNotify) {
  355. CreateAliveChecker(true, true);
  356. ASSERT_TRUE(mock_power_observer_helper_);
  357. StartAliveChecker();
  358. alive_checker_thread_.task_runner()->PostTask(
  359. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Suspend,
  360. base::Unretained(mock_power_observer_helper_)));
  361. // It can take up to the timeout + the check interval until detection. Add a
  362. // margin to this.
  363. EXPECT_FALSE(WaitUntilDetectedDeadWithTimeout(
  364. base::Milliseconds(kTimeoutMs + kCheckIntervalMs + 10)));
  365. EXPECT_FALSE(GetDetectedDead());
  366. alive_checker_thread_.task_runner()->PostTask(
  367. FROM_HERE, base::BindOnce(&MockPowerObserverHelper::Resume,
  368. base::Unretained(mock_power_observer_helper_)));
  369. WaitUntilDetectedDead();
  370. EXPECT_TRUE(GetDetectedDead());
  371. }
  372. } // namespace media