1 // Copyright 2020 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
5 #include "base/test/metrics/histogram_tester.h"
6 #include "content/browser/renderer_host/render_widget_host_impl.h"
7 #include "content/public/browser/render_view_host.h"
8 #include "content/public/test/content_browser_test.h"
9 #include "content/public/test/content_browser_test_utils.h"
10 #include "content/public/test/hit_test_region_observer.h"
11 #include "content/shell/browser/shell.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura/window_tree_host.h"
16 #include "ui/events/test/event_generator.h"
17
18 namespace content {
19
20 class EventLatencyBrowserTest : public ContentBrowserTest {
21 public:
22 EventLatencyBrowserTest() = default;
23 ~EventLatencyBrowserTest() override = default;
24
25 EventLatencyBrowserTest(const EventLatencyBrowserTest&) = delete;
26 EventLatencyBrowserTest& operator=(const EventLatencyBrowserTest&) = delete;
27
28 protected:
GetWidgetHost()29 RenderWidgetHostImpl* GetWidgetHost() {
30 return RenderWidgetHostImpl::From(
31 shell()->web_contents()->GetRenderViewHost()->GetWidget());
32 }
33
34 // Starts the test server and navigates to the test page. Returns after the
35 // navigation is complete.
LoadTestPage()36 void LoadTestPage() {
37 ASSERT_TRUE(embedded_test_server()->Start());
38
39 // Navigate to the test page which has a rAF animation and a main thread
40 // animation running.
41 GURL test_url =
42 embedded_test_server()->GetURL("/event-latency-animation.html");
43 EXPECT_TRUE(NavigateToURL(shell(), test_url));
44
45 aura::Window* content = shell()->web_contents()->GetContentNativeView();
46 content->GetHost()->SetBoundsInPixels(gfx::Rect(800, 600));
47
48 RenderWidgetHostImpl* host = GetWidgetHost();
49 HitTestRegionObserver observer(host->GetFrameSinkId());
50
51 // Wait for the hit test data to be ready.
52 observer.WaitForHitTestData();
53 }
54
FocusButton() const55 void FocusButton() const { ASSERT_TRUE(ExecJs(shell(), "focusButton()")); }
56
StartAnimations() const57 void StartAnimations() const {
58 ASSERT_TRUE(ExecJs(shell(), "startAnimations()"));
59 }
60 };
61
62 // Tests that if a key-press on a page causes a visual update, appropriate event
63 // latency metrics are reported.
IN_PROC_BROWSER_TEST_F(EventLatencyBrowserTest,KeyPressOnButton)64 IN_PROC_BROWSER_TEST_F(EventLatencyBrowserTest, KeyPressOnButton) {
65 base::HistogramTester histogram_tester;
66
67 ASSERT_NO_FATAL_FAILURE(LoadTestPage());
68 FocusButton();
69
70 ui::test::EventGenerator generator(shell()
71 ->web_contents()
72 ->GetRenderWidgetHostView()
73 ->GetNativeView()
74 ->GetRootWindow());
75
76 // Press and release the space key. Since the button on the test page is
77 // focused, this should change the visuals of the button and generate a
78 // compositor frame with appropriate event latency metrics.
79 generator.PressKey(ui::VKEY_SPACE, 0);
80 generator.ReleaseKey(ui::VKEY_SPACE, 0);
81 RunUntilInputProcessed(GetWidgetHost());
82
83 FetchHistogramsFromChildProcesses();
84
85 base::HistogramTester::CountsMap expected_counts = {
86 {"EventLatency.KeyReleased.TotalLatency", 1},
87 };
88 EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("EventLatency."),
89 testing::ContainerEq(expected_counts));
90 }
91
92 // Tests that if a key-press on a page with an animation causes a visual update,
93 // appropriate event latency metrics are reported.
IN_PROC_BROWSER_TEST_F(EventLatencyBrowserTest,KeyPressOnButtonWithAnimation)94 IN_PROC_BROWSER_TEST_F(EventLatencyBrowserTest, KeyPressOnButtonWithAnimation) {
95 base::HistogramTester histogram_tester;
96
97 ASSERT_NO_FATAL_FAILURE(LoadTestPage());
98 StartAnimations();
99 FocusButton();
100
101 ui::test::EventGenerator generator(shell()
102 ->web_contents()
103 ->GetRenderWidgetHostView()
104 ->GetNativeView()
105 ->GetRootWindow());
106
107 // Press and release the space key. Since the button on the test page is
108 // focused, this should change the visuals of the button and generate a
109 // compositor frame with appropriate event latency metrics.
110 generator.PressKey(ui::VKEY_SPACE, 0);
111 generator.ReleaseKey(ui::VKEY_SPACE, 0);
112 RunUntilInputProcessed(GetWidgetHost());
113
114 FetchHistogramsFromChildProcesses();
115
116 base::HistogramTester::CountsMap expected_counts = {
117 {"EventLatency.KeyReleased.TotalLatency", 1},
118 };
119 EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("EventLatency."),
120 testing::ContainerEq(expected_counts));
121 }
122
123 } // namespace content
124