1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/visibility_timer_tab_helper.h"
7 #include "base/test/bind.h"
8 #include "base/test/task_environment.h"
9 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
10 #include "content/public/browser/web_contents.h"
12 class VisibilityTimerTabHelperTest : public ChromeRenderViewHostTestHarness {
14 VisibilityTimerTabHelperTest()
15 : ChromeRenderViewHostTestHarness(
16 base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
19 TEST_F(VisibilityTimerTabHelperTest, Delay) {
20 bool task_executed = false;
21 VisibilityTimerTabHelper::CreateForWebContents(web_contents());
22 VisibilityTimerTabHelper::FromWebContents(web_contents())
23 ->PostTaskAfterVisibleDelay(FROM_HERE,
24 base::BindLambdaForTesting([&task_executed] {
25 EXPECT_FALSE(task_executed);
30 EXPECT_FALSE(task_executed);
32 // The task will be executed after 1 second, but the timer is reset whenever
33 // the tab is not visible, so these 500ms never add up to >= 1 second.
34 for (int n = 0; n < 10; n++) {
35 web_contents()->WasShown();
36 task_environment()->FastForwardBy(base::Milliseconds(500));
37 web_contents()->WasHidden();
40 EXPECT_FALSE(task_executed);
42 // Time elapsed whilst hidden is not counted.
43 // n.b. This line also clears out any old scheduled timer tasks. This is
44 // important, because otherwise Timer::Reset (triggered by
45 // VisibilityTimerTabHelper::WasShown) may choose to re-use an existing
46 // scheduled task, and when it fires Timer::RunScheduledTask will call
47 // TimeTicks::Now() (which unlike task_environment()->NowTicks(), we can't
48 // fake), and miscalculate the remaining delay at which to fire the timer.
49 task_environment()->FastForwardBy(base::Days(1));
51 EXPECT_FALSE(task_executed);
53 // So 500ms is still not enough.
54 web_contents()->WasShown();
55 task_environment()->FastForwardBy(base::Milliseconds(500));
57 EXPECT_FALSE(task_executed);
59 // But 5*500ms > 1 second, so it should now be blocked.
60 for (int n = 0; n < 4; n++)
61 task_environment()->FastForwardBy(base::Milliseconds(500));
63 EXPECT_TRUE(task_executed);
66 TEST_F(VisibilityTimerTabHelperTest, TasksAreQueuedInDormantState) {
67 std::string tasks_executed;
68 VisibilityTimerTabHelper::CreateForWebContents(web_contents());
70 VisibilityTimerTabHelper::FromWebContents(web_contents())
71 ->PostTaskAfterVisibleDelay(
72 FROM_HERE, base::BindLambdaForTesting([&] { tasks_executed += "1"; }),
74 web_contents()->WasShown();
75 task_environment()->FastForwardBy(base::Milliseconds(500));
77 // Add second task. Its timer does not advance until after the first task
79 VisibilityTimerTabHelper::FromWebContents(web_contents())
80 ->PostTaskAfterVisibleDelay(
81 FROM_HERE, base::BindLambdaForTesting([&] { tasks_executed += "2"; }),
84 web_contents()->WasHidden();
85 web_contents()->WasShown();
86 task_environment()->FastForwardBy(base::Milliseconds(990));
88 EXPECT_EQ("", tasks_executed);
90 task_environment()->FastForwardBy(base::Milliseconds(11));
92 EXPECT_EQ("1", tasks_executed);
94 task_environment()->FastForwardBy(base::Milliseconds(1000));
96 EXPECT_EQ("12", tasks_executed);