Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2015 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 "content/browser/media/capture/cursor_renderer_aura.h" | |
| 6 | |
| 7 #include "base/memory/scoped_ptr.h" | |
| 8 #include "base/test/simple_test_tick_clock.h" | |
| 9 #include "base/time/time.h" | |
| 10 #include "media/base/video_frame.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 #include "ui/aura/env.h" | |
| 13 #include "ui/aura/test/aura_test_base.h" | |
| 14 #include "ui/aura/test/test_windows.h" | |
| 15 #include "ui/aura/window.h" | |
| 16 #include "ui/base/resource/resource_bundle.h" | |
| 17 #include "ui/events/event.h" | |
| 18 #include "ui/events/event_utils.h" | |
| 19 #include "ui/wm/core/default_activation_client.h" | |
| 20 #include "ui/wm/core/window_util.h" | |
| 21 | |
| 22 namespace content { | |
| 23 | |
| 24 using aura::test::AuraTestBase; | |
| 25 | |
| 26 class CursorRendererAuraTest : public AuraTestBase { | |
| 27 public: | |
| 28 CursorRendererAuraTest() {} | |
| 29 ~CursorRendererAuraTest() override {} | |
| 30 | |
| 31 void SetUp() override { | |
| 32 AuraTestBase::SetUp(); | |
| 33 // This is needed to avoid duplicate initialization across tests that leads | |
| 34 // to a failure. | |
| 35 if (!ui::ResourceBundle::HasSharedInstance()) { | |
| 36 // Initialize the shared global resource bundle that has bitmap | |
| 37 // resources needed by CursorRenderer | |
| 38 ui::ResourceBundle::InitSharedInstanceWithLocale( | |
| 39 "en-US", NULL, ui::ResourceBundle::LOAD_COMMON_RESOURCES); | |
|
miu
2015/10/29 01:44:49
nit: nullptr instead of NULL
Irfan
2015/10/29 15:34:19
Done.
| |
| 40 } | |
| 41 | |
| 42 window_.reset(aura::test::CreateTestWindowWithBounds( | |
| 43 gfx::Rect(0, 0, 800, 600), root_window())); | |
| 44 cursor_renderer_.reset(new CursorRendererAura(window_.get())); | |
| 45 new wm::DefaultActivationClient(root_window()); | |
| 46 } | |
| 47 | |
| 48 void TearDown() override { | |
| 49 cursor_renderer_.reset(); | |
| 50 window_.reset(); | |
| 51 AuraTestBase::TearDown(); | |
| 52 } | |
| 53 | |
| 54 void SetTickClock(base::SimpleTestTickClock* clock) { | |
| 55 cursor_renderer_->tick_clock_ = clock; | |
| 56 } | |
| 57 | |
| 58 base::TimeDelta Now() { | |
| 59 return cursor_renderer_->tick_clock_->NowTicks() - base::TimeTicks(); | |
| 60 } | |
| 61 | |
| 62 bool CursorDisplayed() { return cursor_renderer_->cursor_displayed_; } | |
| 63 | |
| 64 void RenderCursorOnVideoFrame( | |
| 65 const scoped_refptr<media::VideoFrame>& target) { | |
| 66 cursor_renderer_->RenderOnVideoFrame(target); | |
| 67 } | |
| 68 | |
| 69 void SnapshotCursorState(gfx::Rect region_in_frame) { | |
| 70 cursor_renderer_->SnapshotCursorState(region_in_frame); | |
| 71 } | |
| 72 | |
| 73 void MoveMouseCursorWithinWindow() { | |
| 74 gfx::Point point1(20, 20); | |
| 75 ui::MouseEvent event1(ui::ET_MOUSE_MOVED, point1, point1, Now(), 0, 0); | |
| 76 cursor_renderer_->OnMouseEvent(&event1); | |
| 77 gfx::Point point2(60, 60); | |
| 78 ui::MouseEvent event2(ui::ET_MOUSE_MOVED, point2, point2, Now(), 0, 0); | |
| 79 cursor_renderer_->OnMouseEvent(&event2); | |
| 80 aura::Env::GetInstance()->set_last_mouse_location(point2); | |
| 81 } | |
| 82 | |
| 83 void MoveMouseCursorWithinWindow(gfx::Point point) { | |
| 84 ui::MouseEvent event(ui::ET_MOUSE_MOVED, point, point, Now(), 0, 0); | |
| 85 cursor_renderer_->OnMouseEvent(&event); | |
| 86 aura::Env::GetInstance()->set_last_mouse_location(point); | |
| 87 } | |
| 88 | |
| 89 void MoveMouseCursorOutsideWindow() { | |
| 90 gfx::Point point(1000, 1000); | |
| 91 ui::MouseEvent event1(ui::ET_MOUSE_MOVED, point, point, Now(), 0, 0); | |
| 92 cursor_renderer_->OnMouseEvent(&event1); | |
| 93 aura::Env::GetInstance()->set_last_mouse_location(point); | |
|
sadrul
2015/10/29 06:22:41
Most tests usually use EventGenerator for sending
Irfan
2015/10/29 15:34:19
This allows me to stay in control of clock. Keepin
| |
| 94 } | |
| 95 | |
| 96 // A very simple test of whether there are any non-zero pixels | |
| 97 // in the region |rect| within |frame|. | |
| 98 bool NonZeroPixelsInRegion(scoped_refptr<media::VideoFrame> frame, | |
| 99 gfx::Rect rect) { | |
| 100 bool y_found = false, u_found = false, v_found = false; | |
| 101 for (int y = rect.y(); y < rect.bottom(); ++y) { | |
| 102 uint8* yplane = frame->data(media::VideoFrame::kYPlane) + | |
| 103 y * frame->row_bytes(media::VideoFrame::kYPlane); | |
| 104 uint8* uplane = frame->data(media::VideoFrame::kUPlane) + | |
| 105 (y / 2) * frame->row_bytes(media::VideoFrame::kUPlane); | |
| 106 uint8* vplane = frame->data(media::VideoFrame::kVPlane) + | |
| 107 (y / 2) * frame->row_bytes(media::VideoFrame::kVPlane); | |
| 108 for (int x = rect.x(); x < rect.right(); ++x) { | |
| 109 if (yplane[x] != 0) | |
| 110 y_found = true; | |
| 111 if (uplane[x / 2]) | |
| 112 u_found = true; | |
| 113 if (vplane[x / 2]) | |
| 114 v_found = true; | |
| 115 } | |
| 116 } | |
| 117 return (y_found && u_found && v_found); | |
| 118 } | |
| 119 | |
| 120 protected: | |
| 121 scoped_ptr<aura::Window> window_; | |
| 122 scoped_ptr<CursorRendererAura> cursor_renderer_; | |
| 123 }; | |
| 124 | |
| 125 TEST_F(CursorRendererAuraTest, CursorDuringMouseMovement) { | |
| 126 // Keep window activated. | |
| 127 wm::ActivateWindow(window_.get()); | |
| 128 | |
| 129 EXPECT_FALSE(CursorDisplayed()); | |
| 130 | |
| 131 base::SimpleTestTickClock clock; | |
| 132 SetTickClock(&clock); | |
| 133 | |
| 134 // Cursor displayed after mouse movement. | |
| 135 MoveMouseCursorWithinWindow(); | |
| 136 EXPECT_TRUE(CursorDisplayed()); | |
| 137 | |
| 138 // Cursor not be displayed after idle period. | |
| 139 clock.Advance(base::TimeDelta::FromSeconds(5)); | |
| 140 SnapshotCursorState(gfx::Rect(10, 10, 200, 200)); | |
| 141 EXPECT_FALSE(CursorDisplayed()); | |
| 142 | |
| 143 // Cursor displayed with mouse movement following idle period. | |
| 144 MoveMouseCursorWithinWindow(); | |
| 145 SnapshotCursorState(gfx::Rect(10, 10, 200, 200)); | |
| 146 EXPECT_TRUE(CursorDisplayed()); | |
| 147 | |
| 148 // Cursor not displayed if mouse outside the window | |
| 149 MoveMouseCursorOutsideWindow(); | |
| 150 SnapshotCursorState(gfx::Rect(10, 10, 200, 200)); | |
| 151 EXPECT_FALSE(CursorDisplayed()); | |
| 152 } | |
| 153 | |
| 154 TEST_F(CursorRendererAuraTest, CursorOnActiveWindow) { | |
| 155 EXPECT_FALSE(CursorDisplayed()); | |
| 156 | |
| 157 // Cursor displayed after mouse movement. | |
| 158 MoveMouseCursorWithinWindow(); | |
| 159 EXPECT_TRUE(CursorDisplayed()); | |
| 160 | |
| 161 // Cursor not be displayed if a second window is activated. | |
| 162 scoped_ptr<aura::Window> window2(aura::test::CreateTestWindowWithBounds( | |
| 163 gfx::Rect(0, 0, 800, 600), root_window())); | |
| 164 wm::ActivateWindow(window2.get()); | |
| 165 SnapshotCursorState(gfx::Rect(10, 10, 200, 200)); | |
| 166 EXPECT_FALSE(CursorDisplayed()); | |
| 167 | |
| 168 // Cursor displayed if window activated again. | |
| 169 MoveMouseCursorWithinWindow(); | |
| 170 wm::ActivateWindow(window_.get()); | |
| 171 SnapshotCursorState(gfx::Rect(10, 10, 200, 200)); | |
| 172 EXPECT_TRUE(CursorDisplayed()); | |
| 173 } | |
| 174 | |
| 175 TEST_F(CursorRendererAuraTest, CursorRenderedOnFrame) { | |
| 176 // Keep window activated. | |
| 177 wm::ActivateWindow(window_.get()); | |
| 178 | |
| 179 EXPECT_FALSE(CursorDisplayed()); | |
| 180 | |
| 181 gfx::Size size(800, 600); | |
| 182 scoped_refptr<media::VideoFrame> frame = | |
| 183 media::VideoFrame::CreateZeroInitializedFrame(media::PIXEL_FORMAT_YV12, | |
| 184 size, gfx::Rect(size), size, | |
| 185 base::TimeDelta()); | |
| 186 | |
| 187 MoveMouseCursorWithinWindow(gfx::Point(60, 60)); | |
| 188 SnapshotCursorState(gfx::Rect(size)); | |
| 189 EXPECT_TRUE(CursorDisplayed()); | |
| 190 | |
| 191 EXPECT_FALSE(NonZeroPixelsInRegion(frame, gfx::Rect(50, 50, 70, 70))); | |
| 192 RenderCursorOnVideoFrame(frame); | |
| 193 EXPECT_TRUE(NonZeroPixelsInRegion(frame, gfx::Rect(50, 50, 70, 70))); | |
| 194 } | |
| 195 | |
| 196 } // namespace content | |
| OLD | NEW |