| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2016 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 "chrome/browser/chromeos/accessibility/accessibility_highlight_manager.
h" | |
| 6 | |
| 7 #include "ash/shell.h" | |
| 8 #include "base/bind.h" | |
| 9 #include "base/command_line.h" | |
| 10 #include "base/run_loop.h" | |
| 11 #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h" | |
| 12 #include "chrome/test/base/in_process_browser_test.h" | |
| 13 #include "chromeos/chromeos_switches.h" | |
| 14 #include "content/public/browser/browser_thread.h" | |
| 15 #include "content/public/browser/focused_node_details.h" | |
| 16 #include "content/public/browser/notification_types.h" | |
| 17 #include "ui/aura/window.h" | |
| 18 #include "ui/base/ime/dummy_text_input_client.h" | |
| 19 #include "ui/base/ime/input_method.h" | |
| 20 #include "ui/base/ime/text_input_client.h" | |
| 21 #include "ui/compositor/compositor_switches.h" | |
| 22 #include "ui/events/event_utils.h" | |
| 23 #include "ui/gfx/image/image.h" | |
| 24 #include "ui/snapshot/snapshot.h" | |
| 25 | |
| 26 namespace chromeos { | |
| 27 namespace { | |
| 28 | |
| 29 class MockTextInputClient : public ui::DummyTextInputClient { | |
| 30 public: | |
| 31 MockTextInputClient() : ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_TEXT) {} | |
| 32 | |
| 33 void SetCaretBounds(const gfx::Rect& bounds) { caret_bounds_ = bounds; } | |
| 34 | |
| 35 private: | |
| 36 gfx::Rect GetCaretBounds() const override { return caret_bounds_; } | |
| 37 | |
| 38 gfx::Rect caret_bounds_; | |
| 39 | |
| 40 DISALLOW_COPY_AND_ASSIGN(MockTextInputClient); | |
| 41 }; | |
| 42 | |
| 43 class TestAccessibilityHighlightManager : public AccessibilityHighlightManager { | |
| 44 public: | |
| 45 TestAccessibilityHighlightManager() {} | |
| 46 | |
| 47 void OnCaretBoundsChanged(const ui::TextInputClient* client) override { | |
| 48 AccessibilityHighlightManager::OnCaretBoundsChanged(client); | |
| 49 } | |
| 50 void OnMouseEvent(ui::MouseEvent* event) override { | |
| 51 AccessibilityHighlightManager::OnMouseEvent(event); | |
| 52 } | |
| 53 void Observe(int type, | |
| 54 const content::NotificationSource& source, | |
| 55 const content::NotificationDetails& details) override { | |
| 56 AccessibilityHighlightManager::Observe(type, source, details); | |
| 57 } | |
| 58 | |
| 59 private: | |
| 60 bool IsCursorVisible() override { return true; } | |
| 61 | |
| 62 DISALLOW_COPY_AND_ASSIGN(TestAccessibilityHighlightManager); | |
| 63 }; | |
| 64 | |
| 65 } // namespace | |
| 66 | |
| 67 class AccessibilityHighlightManagerTest : public InProcessBrowserTest { | |
| 68 protected: | |
| 69 AccessibilityHighlightManagerTest() {} | |
| 70 ~AccessibilityHighlightManagerTest() override {} | |
| 71 | |
| 72 void SetUp() override { | |
| 73 AccessibilityFocusRingController::GetInstance()->SetNoFadeForTesting(); | |
| 74 InProcessBrowserTest::SetUp(); | |
| 75 } | |
| 76 | |
| 77 void SetUpCommandLine(base::CommandLine* command_line) override { | |
| 78 command_line->AppendSwitch(::switches::kEnablePixelOutputInTests); | |
| 79 } | |
| 80 | |
| 81 void CaptureBeforeImage(const gfx::Rect& bounds) { | |
| 82 Capture(bounds); | |
| 83 image_.AsBitmap().deepCopyTo(&before_bmp_); | |
| 84 } | |
| 85 | |
| 86 void CaptureAfterImage(const gfx::Rect& bounds) { | |
| 87 Capture(bounds); | |
| 88 image_.AsBitmap().deepCopyTo(&after_bmp_); | |
| 89 } | |
| 90 | |
| 91 void ComputeImageStats() { | |
| 92 diff_count_ = 0; | |
| 93 double accum[4] = {0, 0, 0, 0}; | |
| 94 SkAutoLockPixels lock_before(before_bmp_); | |
| 95 SkAutoLockPixels lock_after(after_bmp_); | |
| 96 for (int x = 0; x < before_bmp_.width(); ++x) { | |
| 97 for (int y = 0; y < before_bmp_.height(); ++y) { | |
| 98 SkColor before_color = before_bmp_.getColor(x, y); | |
| 99 SkColor after_color = after_bmp_.getColor(x, y); | |
| 100 if (before_color != after_color) { | |
| 101 diff_count_++; | |
| 102 accum[0] += SkColorGetB(after_color); | |
| 103 accum[1] += SkColorGetG(after_color); | |
| 104 accum[2] += SkColorGetR(after_color); | |
| 105 accum[3] += SkColorGetA(after_color); | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 average_diff_color_ = | |
| 110 SkColorSetARGB(static_cast<unsigned char>(accum[3] / diff_count_), | |
| 111 static_cast<unsigned char>(accum[2] / diff_count_), | |
| 112 static_cast<unsigned char>(accum[1] / diff_count_), | |
| 113 static_cast<unsigned char>(accum[0] / diff_count_)); | |
| 114 } | |
| 115 | |
| 116 int diff_count() { return diff_count_; } | |
| 117 SkColor average_diff_color() { return average_diff_color_; } | |
| 118 | |
| 119 private: | |
| 120 void GotSnapshot(const gfx::Image& image) { | |
| 121 image_ = image; | |
| 122 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | |
| 123 run_loop_quitter_); | |
| 124 } | |
| 125 | |
| 126 void Capture(const gfx::Rect& bounds) { | |
| 127 aura::Window* window = ash::Shell::GetPrimaryRootWindow(); | |
| 128 ui::GrabWindowSnapshotAndScaleAsync( | |
| 129 window, bounds, bounds.size(), | |
| 130 content::BrowserThread::GetBlockingPool(), | |
| 131 base::Bind(&AccessibilityHighlightManagerTest::GotSnapshot, this)); | |
| 132 base::RunLoop run_loop; | |
| 133 run_loop_quitter_ = run_loop.QuitClosure(); | |
| 134 run_loop.Run(); | |
| 135 } | |
| 136 | |
| 137 base::Closure run_loop_quitter_; | |
| 138 gfx::Image image_; | |
| 139 SkBitmap before_bmp_; | |
| 140 SkBitmap after_bmp_; | |
| 141 int diff_count_; | |
| 142 SkColor average_diff_color_; | |
| 143 | |
| 144 DISALLOW_COPY_AND_ASSIGN(AccessibilityHighlightManagerTest); | |
| 145 }; | |
| 146 | |
| 147 IN_PROC_BROWSER_TEST_F(AccessibilityHighlightManagerTest, | |
| 148 TestCaretRingDrawsBluePixels) { | |
| 149 gfx::Rect capture_bounds(200, 300, 100, 100); | |
| 150 gfx::Rect caret_bounds(230, 330, 1, 25); | |
| 151 | |
| 152 CaptureBeforeImage(capture_bounds); | |
| 153 | |
| 154 TestAccessibilityHighlightManager manager; | |
| 155 manager.HighlightCaret(true); | |
| 156 MockTextInputClient text_input_client; | |
| 157 text_input_client.SetCaretBounds(caret_bounds); | |
| 158 manager.OnCaretBoundsChanged(&text_input_client); | |
| 159 | |
| 160 CaptureAfterImage(capture_bounds); | |
| 161 ComputeImageStats(); | |
| 162 | |
| 163 // This is a smoke test to assert that something is drawn in the right | |
| 164 // part of the screen of approximately the right size and color. | |
| 165 // There's deliberately some tolerance for tiny errors. | |
| 166 EXPECT_NEAR(1487, diff_count(), 50); | |
| 167 EXPECT_NEAR(175, SkColorGetR(average_diff_color()), 5); | |
| 168 EXPECT_NEAR(175, SkColorGetG(average_diff_color()), 5); | |
| 169 EXPECT_NEAR(255, SkColorGetB(average_diff_color()), 5); | |
| 170 } | |
| 171 | |
| 172 IN_PROC_BROWSER_TEST_F(AccessibilityHighlightManagerTest, | |
| 173 TestCursorRingDrawsRedPixels) { | |
| 174 gfx::Rect capture_bounds(200, 300, 100, 100); | |
| 175 gfx::Point cursor_point(250, 350); | |
| 176 | |
| 177 CaptureBeforeImage(capture_bounds); | |
| 178 | |
| 179 TestAccessibilityHighlightManager manager; | |
| 180 manager.HighlightCursor(true); | |
| 181 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, cursor_point, cursor_point, | |
| 182 ui::EventTimeForNow(), 0, 0); | |
| 183 manager.OnMouseEvent(&mouse_move); | |
| 184 CaptureAfterImage(capture_bounds); | |
| 185 ComputeImageStats(); | |
| 186 | |
| 187 // This is a smoke test to assert that something is drawn in the right | |
| 188 // part of the screen of approximately the right size and color. | |
| 189 // There's deliberately some tolerance for tiny errors. | |
| 190 EXPECT_NEAR(1521, diff_count(), 50); | |
| 191 EXPECT_NEAR(255, SkColorGetR(average_diff_color()), 5); | |
| 192 EXPECT_NEAR(176, SkColorGetG(average_diff_color()), 5); | |
| 193 EXPECT_NEAR(176, SkColorGetB(average_diff_color()), 5); | |
| 194 } | |
| 195 | |
| 196 IN_PROC_BROWSER_TEST_F(AccessibilityHighlightManagerTest, | |
| 197 TestFocusRingDrawsOrangePixels) { | |
| 198 gfx::Rect capture_bounds(200, 300, 100, 100); | |
| 199 gfx::Rect focus_bounds(230, 330, 40, 40); | |
| 200 | |
| 201 CaptureBeforeImage(capture_bounds); | |
| 202 | |
| 203 TestAccessibilityHighlightManager manager; | |
| 204 manager.HighlightFocus(true); | |
| 205 content::FocusedNodeDetails details{false, focus_bounds}; | |
| 206 manager.Observe(content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, | |
| 207 content::Source<AccessibilityHighlightManagerTest>(this), | |
| 208 content::Details<content::FocusedNodeDetails>(&details)); | |
| 209 CaptureAfterImage(capture_bounds); | |
| 210 ComputeImageStats(); | |
| 211 | |
| 212 // This is a smoke test to assert that something is drawn in the right | |
| 213 // part of the screen of approximately the right size and color. | |
| 214 // There's deliberately some tolerance for tiny errors. | |
| 215 EXPECT_NEAR(1608, diff_count(), 50); | |
| 216 EXPECT_NEAR(255, SkColorGetR(average_diff_color()), 5); | |
| 217 EXPECT_NEAR(201, SkColorGetG(average_diff_color()), 5); | |
| 218 EXPECT_NEAR(152, SkColorGetB(average_diff_color()), 5); | |
| 219 } | |
| 220 | |
| 221 } // namespace chromeos | |
| OLD | NEW |