Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / snapshot / snapshot_aura_unittest.cc
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 "base/bind.h"
8 #include "base/test/test_simple_task_runner.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/aura/test/aura_test_helper.h"
11 #include "ui/aura/test/test_screen.h"
12 #include "ui/aura/test/test_window_delegate.h"
13 #include "ui/aura/test/test_windows.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura/window_event_dispatcher.h"
16 #include "ui/compositor/compositor.h"
17 #include "ui/compositor/layer.h"
18 #include "ui/compositor/test/context_factories_for_test.h"
19 #include "ui/compositor/test/draw_waiter_for_test.h"
20 #include "ui/gfx/canvas.h"
21 #include "ui/gfx/gfx_paths.h"
22 #include "ui/gfx/image/image.h"
23 #include "ui/gfx/rect.h"
24 #include "ui/gfx/size_conversions.h"
25 #include "ui/gfx/transform.h"
26 #include "ui/gl/gl_implementation.h"
27 #include "ui/wm/core/default_activation_client.h"
28
29 namespace ui {
30 namespace {
31
32 SkColor GetExpectedColorForPoint(int x, int y) {
33   return SkColorSetRGB(std::min(x, 255), std::min(y, 255), 0);
34 }
35
36 // Paint simple rectangle on the specified aura window.
37 class TestPaintingWindowDelegate : public aura::test::TestWindowDelegate {
38  public:
39   explicit TestPaintingWindowDelegate(const gfx::Size& window_size)
40       : window_size_(window_size) {
41   }
42
43   ~TestPaintingWindowDelegate() override {}
44
45   void OnPaint(gfx::Canvas* canvas) override {
46     for (int y = 0; y < window_size_.height(); ++y) {
47       for (int x = 0; x < window_size_.width(); ++x)
48         canvas->FillRect(gfx::Rect(x, y, 1, 1), GetExpectedColorForPoint(x, y));
49     }
50   }
51
52  private:
53   gfx::Size window_size_;
54
55   DISALLOW_COPY_AND_ASSIGN(TestPaintingWindowDelegate);
56 };
57
58 size_t GetFailedPixelsCountWithScaleFactor(const gfx::Image& image,
59                                            int scale_factor) {
60   const SkBitmap* bitmap = image.ToSkBitmap();
61   uint32* bitmap_data = reinterpret_cast<uint32*>(
62       bitmap->pixelRef()->pixels());
63   size_t result = 0;
64   for (int y = 0; y < bitmap->height(); y += scale_factor) {
65     for (int x = 0; x < bitmap->width(); x += scale_factor) {
66       if (static_cast<SkColor>(bitmap_data[x + y * bitmap->width()]) !=
67           GetExpectedColorForPoint(x / scale_factor, y / scale_factor)) {
68         ++result;
69       }
70     }
71   }
72   return result;
73 }
74
75 size_t GetFailedPixelsCount(const gfx::Image& image) {
76   return GetFailedPixelsCountWithScaleFactor(image, 1);
77 }
78
79 }  // namespace
80
81 class SnapshotAuraTest : public testing::Test {
82  public:
83   SnapshotAuraTest() {}
84   ~SnapshotAuraTest() override {}
85
86   void SetUp() override {
87     testing::Test::SetUp();
88
89     // The ContextFactory must exist before any Compositors are created.
90     // Snapshot test tests real drawing and readback, so needs pixel output.
91     bool enable_pixel_output = true;
92     ui::ContextFactory* context_factory =
93         ui::InitializeContextFactoryForTests(enable_pixel_output);
94
95     helper_.reset(
96         new aura::test::AuraTestHelper(base::MessageLoopForUI::current()));
97     helper_->SetUp(context_factory);
98     new ::wm::DefaultActivationClient(helper_->root_window());
99   }
100
101   void TearDown() override {
102     test_window_.reset();
103     delegate_.reset();
104     helper_->RunAllPendingInMessageLoop();
105     helper_->TearDown();
106     ui::TerminateContextFactoryForTests();
107     testing::Test::TearDown();
108   }
109
110  protected:
111   aura::Window* test_window() { return test_window_.get(); }
112   aura::Window* root_window() { return helper_->root_window(); }
113   aura::TestScreen* test_screen() { return helper_->test_screen(); }
114
115   void WaitForDraw() {
116     helper_->host()->compositor()->ScheduleDraw();
117     ui::DrawWaiterForTest::Wait(helper_->host()->compositor());
118   }
119
120   void SetupTestWindow(const gfx::Rect& window_bounds) {
121     delegate_.reset(new TestPaintingWindowDelegate(window_bounds.size()));
122     test_window_.reset(aura::test::CreateTestWindowWithDelegate(
123         delegate_.get(), 0, window_bounds, root_window()));
124   }
125
126   gfx::Image GrabSnapshotForTestWindow() {
127     gfx::Rect source_rect(test_window_->bounds().size());
128     aura::Window::ConvertRectToTarget(
129         test_window(), root_window(), &source_rect);
130
131     scoped_refptr<base::TestSimpleTaskRunner> task_runner(
132         new base::TestSimpleTaskRunner());
133     scoped_refptr<SnapshotHolder> holder(new SnapshotHolder);
134     ui::GrabWindowSnapshotAsync(
135         root_window(),
136         source_rect,
137         task_runner,
138         base::Bind(&SnapshotHolder::SnapshotCallback, holder));
139
140     // Wait for copy response.
141     WaitForDraw();
142     // Run internal snapshot callback to scale/rotate response image.
143     task_runner->RunUntilIdle();
144     // Run SnapshotHolder callback.
145     helper_->RunAllPendingInMessageLoop();
146
147     if (holder->completed())
148       return holder->image();
149
150     // Callback never called.
151     NOTREACHED();
152     return gfx::Image();
153   }
154
155  private:
156   class SnapshotHolder : public base::RefCountedThreadSafe<SnapshotHolder> {
157    public:
158     SnapshotHolder() : completed_(false) {}
159
160     void SnapshotCallback(scoped_refptr<base::RefCountedBytes> png_data) {
161       DCHECK(!completed_);
162       image_ = gfx::Image::CreateFrom1xPNGBytes(&(png_data->data()[0]),
163                                                 png_data->size());
164       completed_ = true;
165     }
166     bool completed() const {
167       return completed_;
168     };
169     const gfx::Image& image() const { return image_; }
170
171    private:
172     friend class base::RefCountedThreadSafe<SnapshotHolder>;
173
174     virtual ~SnapshotHolder() {}
175
176     gfx::Image image_;
177     bool completed_;
178   };
179
180   scoped_ptr<aura::test::AuraTestHelper> helper_;
181   scoped_ptr<aura::Window> test_window_;
182   scoped_ptr<TestPaintingWindowDelegate> delegate_;
183   std::vector<unsigned char> png_representation_;
184
185   DISALLOW_COPY_AND_ASSIGN(SnapshotAuraTest);
186 };
187
188 TEST_F(SnapshotAuraTest, FullScreenWindow) {
189   SetupTestWindow(root_window()->bounds());
190   WaitForDraw();
191
192   gfx::Image snapshot = GrabSnapshotForTestWindow();
193   EXPECT_EQ(test_window()->bounds().size().ToString(),
194             snapshot.Size().ToString());
195   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
196 }
197
198 TEST_F(SnapshotAuraTest, PartialBounds) {
199   gfx::Rect test_bounds(100, 100, 300, 200);
200   SetupTestWindow(test_bounds);
201   WaitForDraw();
202
203   gfx::Image snapshot = GrabSnapshotForTestWindow();
204   EXPECT_EQ(test_bounds.size().ToString(), snapshot.Size().ToString());
205   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
206 }
207
208 TEST_F(SnapshotAuraTest, Rotated) {
209   test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
210
211   gfx::Rect test_bounds(100, 100, 300, 200);
212   SetupTestWindow(test_bounds);
213   WaitForDraw();
214
215   gfx::Image snapshot = GrabSnapshotForTestWindow();
216   EXPECT_EQ(test_bounds.size().ToString(), snapshot.Size().ToString());
217   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
218 }
219
220 TEST_F(SnapshotAuraTest, UIScale) {
221   const float kUIScale = 1.25f;
222   test_screen()->SetUIScale(kUIScale);
223
224   gfx::Rect test_bounds(100, 100, 300, 200);
225   SetupTestWindow(test_bounds);
226   WaitForDraw();
227
228   // Snapshot always captures the physical pixels.
229   gfx::SizeF snapshot_size(test_bounds.size());
230
231   gfx::Image snapshot = GrabSnapshotForTestWindow();
232   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
233             snapshot.Size().ToString());
234   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
235 }
236
237 TEST_F(SnapshotAuraTest, DeviceScaleFactor) {
238   test_screen()->SetDeviceScaleFactor(2.0f);
239
240   gfx::Rect test_bounds(100, 100, 150, 100);
241   SetupTestWindow(test_bounds);
242   WaitForDraw();
243
244   // Snapshot always captures the physical pixels.
245   gfx::SizeF snapshot_size(test_bounds.size());
246   snapshot_size.Scale(2.0f);
247
248   gfx::Image snapshot = GrabSnapshotForTestWindow();
249   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
250             snapshot.Size().ToString());
251   EXPECT_EQ(0u, GetFailedPixelsCountWithScaleFactor(snapshot, 2));
252 }
253
254 TEST_F(SnapshotAuraTest, RotateAndUIScale) {
255   const float kUIScale = 1.25f;
256   test_screen()->SetUIScale(kUIScale);
257   test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
258
259   gfx::Rect test_bounds(100, 100, 300, 200);
260   SetupTestWindow(test_bounds);
261   WaitForDraw();
262
263   // Snapshot always captures the physical pixels.
264   gfx::SizeF snapshot_size(test_bounds.size());
265
266   gfx::Image snapshot = GrabSnapshotForTestWindow();
267   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
268             snapshot.Size().ToString());
269   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
270 }
271
272 TEST_F(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) {
273   test_screen()->SetDeviceScaleFactor(2.0f);
274   const float kUIScale = 1.25f;
275   test_screen()->SetUIScale(kUIScale);
276   test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
277
278   gfx::Rect test_bounds(20, 30, 150, 100);
279   SetupTestWindow(test_bounds);
280   WaitForDraw();
281
282   // Snapshot always captures the physical pixels.
283   gfx::SizeF snapshot_size(test_bounds.size());
284   snapshot_size.Scale(2.0f);
285
286   gfx::Image snapshot = GrabSnapshotForTestWindow();
287   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
288             snapshot.Size().ToString());
289   EXPECT_EQ(0u, GetFailedPixelsCountWithScaleFactor(snapshot, 2));
290 }
291
292 }  // namespace ui