snapshot_aura_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2013 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 "ui/snapshot/snapshot.h"
6
7#include "testing/gtest/include/gtest/gtest.h"
8#include "ui/aura/root_window.h"
9#include "ui/aura/test/aura_test_helper.h"
10#include "ui/aura/test/test_screen.h"
11#include "ui/aura/test/test_window_delegate.h"
12#include "ui/aura/test/test_windows.h"
13#include "ui/aura/window.h"
14#include "ui/compositor/compositor_setup.h"
15#include "ui/compositor/layer.h"
16#include "ui/gfx/canvas.h"
17#include "ui/gfx/gfx_paths.h"
18#include "ui/gfx/image/image.h"
19#include "ui/gfx/rect.h"
20#include "ui/gfx/size_conversions.h"
21#include "ui/gfx/transform.h"
22#include "ui/gl/gl_implementation.h"
23
24namespace ui {
25namespace {
26const SkColor kPaintColor = SK_ColorRED;
27
28// Paint simple rectangle on the specified aura window.
29class TestPaintingWindowDelegate : public aura::test::TestWindowDelegate {
30 public:
31  explicit TestPaintingWindowDelegate(const gfx::Size& window_size)
32      : window_size_(window_size) {
33  }
34
35  virtual ~TestPaintingWindowDelegate() {
36  }
37
38  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
39    canvas->FillRect(gfx::Rect(window_size_), kPaintColor);
40  }
41
42 private:
43  gfx::Size window_size_;
44
45  DISALLOW_COPY_AND_ASSIGN(TestPaintingWindowDelegate);
46};
47
48size_t GetFailedPixelsCount(const gfx::Image& image) {
49  const SkBitmap* bitmap = image.ToSkBitmap();
50  uint32* bitmap_data = reinterpret_cast<uint32*>(
51      bitmap->pixelRef()->pixels());
52  size_t result = 0;
53  for (int i = 0; i < bitmap->width() * bitmap->height(); ++i) {
54    if (static_cast<SkColor>(bitmap_data[i]) != kPaintColor)
55      ++result;
56  }
57  return result;
58}
59
60}  // namespace
61
62class SnapshotAuraTest : public testing::Test {
63 public:
64  SnapshotAuraTest() {}
65  virtual ~SnapshotAuraTest() {}
66
67  virtual void SetUp() OVERRIDE {
68    testing::Test::SetUp();
69    helper_.reset(new aura::test::AuraTestHelper(MessageLoopForUI::current()));
70    helper_->SetUp();
71  }
72
73  virtual void TearDown() OVERRIDE {
74    test_window_.reset();
75    delegate_.reset();
76    helper_->RunAllPendingInMessageLoop();
77    helper_->TearDown();
78    testing::Test::TearDown();
79  }
80
81 protected:
82  aura::Window* test_window() { return test_window_.get(); }
83  aura::RootWindow* root_window() { return helper_->root_window(); }
84  aura::TestScreen* test_screen() { return helper_->test_screen(); }
85
86  void WaitForDraw() {
87    root_window()->compositor()->ScheduleDraw();
88    ui::DrawWaiterForTest::Wait(root_window()->compositor());
89  }
90
91  void SetupTestWindow(const gfx::Rect& window_bounds) {
92    delegate_.reset(new TestPaintingWindowDelegate(window_bounds.size()));
93    test_window_.reset(aura::test::CreateTestWindowWithDelegate(
94        delegate_.get(), 0, window_bounds, root_window()));
95  }
96
97  gfx::Image GrabSnapshotForTestWindow() {
98    std::vector<unsigned char> png_representation;
99    gfx::Rect local_bounds(test_window_->bounds().size());
100    ui::GrabWindowSnapshot(test_window(), &png_representation, local_bounds);
101    return gfx::Image::CreateFrom1xPNGBytes(
102      &(png_representation[0]), png_representation.size());
103  }
104
105 private:
106  scoped_ptr<aura::test::AuraTestHelper> helper_;
107  scoped_ptr<aura::Window> test_window_;
108  scoped_ptr<TestPaintingWindowDelegate> delegate_;
109  std::vector<unsigned char> png_representation_;
110
111  DISALLOW_COPY_AND_ASSIGN(SnapshotAuraTest);
112};
113
114TEST_F(SnapshotAuraTest, FullScreenWindow) {
115  SetupTestWindow(root_window()->bounds());
116  WaitForDraw();
117
118  gfx::Image snapshot = GrabSnapshotForTestWindow();
119  EXPECT_EQ(test_window()->bounds().size().ToString(),
120            snapshot.Size().ToString());
121  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
122}
123
124TEST_F(SnapshotAuraTest, PartialBounds) {
125  gfx::Rect test_bounds(100, 100, 300, 200);
126  SetupTestWindow(test_bounds);
127  WaitForDraw();
128
129  gfx::Image snapshot = GrabSnapshotForTestWindow();
130  EXPECT_EQ(test_bounds.size().ToString(),
131            snapshot.Size().ToString());
132  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
133}
134
135TEST_F(SnapshotAuraTest, Rotated) {
136  test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
137
138  gfx::Rect test_bounds(100, 100, 300, 200);
139  SetupTestWindow(test_bounds);
140  WaitForDraw();
141
142  gfx::Image snapshot = GrabSnapshotForTestWindow();
143  EXPECT_EQ(test_bounds.size().ToString(),
144            snapshot.Size().ToString());
145  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
146}
147
148TEST_F(SnapshotAuraTest, UIScale) {
149  const float kUIScale = 1.25f;
150  test_screen()->SetUIScale(kUIScale);
151
152  gfx::Rect test_bounds(100, 100, 300, 200);
153  SetupTestWindow(test_bounds);
154  WaitForDraw();
155
156  // Snapshot always captures the physical pixels.
157  gfx::SizeF snapshot_size(test_bounds.size());
158  snapshot_size.Scale(1.0f / kUIScale);
159
160  gfx::Image snapshot = GrabSnapshotForTestWindow();
161  EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
162            snapshot.Size().ToString());
163  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
164}
165
166TEST_F(SnapshotAuraTest, DeviceScaleFactor) {
167  test_screen()->SetDeviceScaleFactor(2.0f);
168
169  gfx::Rect test_bounds(100, 100, 150, 100);
170  SetupTestWindow(test_bounds);
171  WaitForDraw();
172
173  // Snapshot always captures the physical pixels.
174  gfx::SizeF snapshot_size(test_bounds.size());
175  snapshot_size.Scale(2.0f);
176
177  gfx::Image snapshot = GrabSnapshotForTestWindow();
178  EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
179            snapshot.Size().ToString());
180  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
181}
182
183TEST_F(SnapshotAuraTest, RotateAndUIScale) {
184  const float kUIScale = 1.25f;
185  test_screen()->SetUIScale(kUIScale);
186  test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
187
188  gfx::Rect test_bounds(100, 100, 300, 200);
189  SetupTestWindow(test_bounds);
190  WaitForDraw();
191
192  // Snapshot always captures the physical pixels.
193  gfx::SizeF snapshot_size(test_bounds.size());
194  snapshot_size.Scale(1.0f / kUIScale);
195
196  gfx::Image snapshot = GrabSnapshotForTestWindow();
197  EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
198            snapshot.Size().ToString());
199  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
200}
201
202TEST_F(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) {
203  test_screen()->SetDeviceScaleFactor(2.0f);
204  const float kUIScale = 1.25f;
205  test_screen()->SetUIScale(kUIScale);
206  test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
207
208  gfx::Rect test_bounds(20, 30, 150, 100);
209  SetupTestWindow(test_bounds);
210  WaitForDraw();
211
212  // Snapshot always captures the physical pixels.
213  gfx::SizeF snapshot_size(test_bounds.size());
214  snapshot_size.Scale(2.0f / kUIScale);
215
216  gfx::Image snapshot = GrabSnapshotForTestWindow();
217  EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
218            snapshot.Size().ToString());
219  EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
220}
221
222}  // namespace ui
223