1// Copyright 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 "ash/desktop_background/wallpaper_resizer.h"
6
7#include "ash/desktop_background/wallpaper_resizer_observer.h"
8#include "base/message_loop/message_loop.h"
9#include "content/public/test/test_browser_thread.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "ui/gfx/image/image_skia_rep.h"
12
13using aura::Window;
14
15namespace {
16
17const int kTestImageWidth = 5;
18const int kTestImageHeight = 2;
19const int kTargetWidth = 1;
20const int kTargetHeight = 1;
21const uint32_t kExpectedCenter = 0x02020202u;
22const uint32_t kExpectedCenterCropped = 0x03030303u;
23const uint32_t kExpectedStretch = 0x04040404u;
24const uint32_t kExpectedTile = 0;
25
26gfx::ImageSkia CreateTestImage(const gfx::Size& size) {
27  SkBitmap src;
28  int w = size.width();
29  int h = size.height();
30  src.allocN32Pixels(w, h);
31
32  // Fill bitmap with data.
33  for (int y = 0; y < h; ++y) {
34    for (int x = 0; x < w; ++x) {
35      const uint8_t component = static_cast<uint8_t>(y * w + x);
36      const SkColor pixel = SkColorSetARGB(component, component,
37                                           component, component);
38      *(src.getAddr32(x, y)) = pixel;
39    }
40  }
41
42  gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(src);
43  return image;
44}
45
46bool IsColor(const gfx::ImageSkia& image, const uint32_t expect) {
47  EXPECT_EQ(image.width(), kTargetWidth);
48  EXPECT_EQ(image.height(), kTargetHeight);
49  const SkBitmap* image_bitmap = image.bitmap();
50  SkAutoLockPixels image_lock(*image_bitmap);
51  return *image_bitmap->getAddr32(0, 0) == expect;
52}
53
54}  // namespace
55
56namespace ash {
57
58class WallpaperResizerTest : public testing::Test,
59                             public WallpaperResizerObserver {
60 public:
61  WallpaperResizerTest()
62      : ui_thread_(content::BrowserThread::UI, &message_loop_) {
63  }
64  virtual ~WallpaperResizerTest() {}
65
66  gfx::ImageSkia Resize(const gfx::ImageSkia& image,
67                        const gfx::Size& target_size,
68                        WallpaperLayout layout) {
69    scoped_ptr<WallpaperResizer> resizer;
70    resizer.reset(new WallpaperResizer(image, target_size, layout));
71    resizer->AddObserver(this);
72    resizer->StartResize();
73    WaitForResize();
74    resizer->RemoveObserver(this);
75    return resizer->image();
76  }
77
78  void WaitForResize() {
79    message_loop_.Run();
80  }
81
82  virtual void OnWallpaperResized() OVERRIDE {
83    message_loop_.Quit();
84  }
85
86 private:
87  base::MessageLoop message_loop_;
88  content::TestBrowserThread ui_thread_;
89
90  DISALLOW_COPY_AND_ASSIGN(WallpaperResizerTest);
91};
92
93TEST_F(WallpaperResizerTest, BasicResize) {
94  // Keeps in sync with WallpaperLayout enum.
95  WallpaperLayout layouts[4] = {
96      WALLPAPER_LAYOUT_CENTER,
97      WALLPAPER_LAYOUT_CENTER_CROPPED,
98      WALLPAPER_LAYOUT_STRETCH,
99      WALLPAPER_LAYOUT_TILE,
100  };
101  const int length = arraysize(layouts);
102
103  for (int i = 0; i < length; i++) {
104    WallpaperLayout layout = layouts[i];
105    gfx::ImageSkia small_image(gfx::ImageSkiaRep(gfx::Size(10, 20), 1.0f));
106
107    gfx::ImageSkia resized_small = Resize(small_image, gfx::Size(800, 600),
108                                          layout);
109    EXPECT_EQ(10, resized_small.width());
110    EXPECT_EQ(20, resized_small.height());
111
112    gfx::ImageSkia large_image(gfx::ImageSkiaRep(gfx::Size(1000, 1000), 1.0f));
113    gfx::ImageSkia resized_large = Resize(large_image, gfx::Size(800, 600),
114                                          layout);
115    EXPECT_EQ(800, resized_large.width());
116    EXPECT_EQ(600, resized_large.height());
117  }
118}
119
120// Test for crbug.com/244629. "CENTER_CROPPED generates the same image as
121// STRETCH layout"
122TEST_F(WallpaperResizerTest, AllLayoutDifferent) {
123  gfx::ImageSkia image = CreateTestImage(
124      gfx::Size(kTestImageWidth, kTestImageHeight));
125
126  gfx::Size target_size = gfx::Size(kTargetWidth, kTargetHeight);
127  gfx::ImageSkia center = Resize(image, target_size, WALLPAPER_LAYOUT_CENTER);
128
129  gfx::ImageSkia center_cropped = Resize(image, target_size,
130                                         WALLPAPER_LAYOUT_CENTER_CROPPED);
131
132  gfx::ImageSkia stretch = Resize(image, target_size, WALLPAPER_LAYOUT_STRETCH);
133
134  gfx::ImageSkia tile = Resize(image, target_size, WALLPAPER_LAYOUT_TILE);
135
136  EXPECT_TRUE(IsColor(center, kExpectedCenter));
137  EXPECT_TRUE(IsColor(center_cropped, kExpectedCenterCropped));
138  EXPECT_TRUE(IsColor(stretch, kExpectedStretch));
139  EXPECT_TRUE(IsColor(tile, kExpectedTile));
140}
141
142TEST_F(WallpaperResizerTest, ImageId) {
143  gfx::ImageSkia image = CreateTestImage(
144      gfx::Size(kTestImageWidth, kTestImageHeight));
145
146  // Create a WallpaperResizer and check that it reports an original image ID
147  // both pre- and post-resize that matches the ID returned by GetImageId().
148  WallpaperResizer resizer(image, gfx::Size(10, 20), WALLPAPER_LAYOUT_STRETCH);
149  EXPECT_EQ(WallpaperResizer::GetImageId(image), resizer.original_image_id());
150  resizer.AddObserver(this);
151  resizer.StartResize();
152  WaitForResize();
153  resizer.RemoveObserver(this);
154  EXPECT_EQ(WallpaperResizer::GetImageId(image), resizer.original_image_id());
155}
156
157}  // namespace ash
158