1// Copyright 2014 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/wm/core/shadow.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/path_service.h"
9#include "third_party/skia/include/core/SkBitmap.h"
10#include "ui/aura/test/aura_test_base.h"
11#include "ui/aura/test/test_windows.h"
12#include "ui/aura/window.h"
13#include "ui/base/resource/resource_bundle.h"
14#include "ui/base/ui_base_paths.h"
15#include "ui/compositor/layer.h"
16#include "ui/compositor/layer_tree_owner.h"
17#include "ui/resources/grit/ui_resources.h"
18
19namespace wm {
20
21namespace {
22
23const int kSmallBitmapSize = 129;
24const int kLargeBitmapSize = 269;
25
26// Mock for the ResourceBundle::Delegate class.
27class MockResourceBundleDelegate : public ui::ResourceBundle::Delegate {
28 public:
29  MockResourceBundleDelegate() : last_resource_id_(0) {
30    SkBitmap bitmap_small, bitmap_large;
31    bitmap_small.allocPixels(
32        SkImageInfo::MakeN32Premul(kSmallBitmapSize, kSmallBitmapSize));
33    bitmap_large.allocPixels(
34        SkImageInfo::MakeN32Premul(kLargeBitmapSize, kLargeBitmapSize));
35    image_small_ = gfx::Image::CreateFrom1xBitmap(bitmap_small);
36    image_large_ = gfx::Image::CreateFrom1xBitmap(bitmap_large);
37  }
38  virtual ~MockResourceBundleDelegate() {}
39
40  // ResourceBundle::Delegate:
41  virtual base::FilePath GetPathForResourcePack(
42      const base::FilePath& pack_path,
43      ui::ScaleFactor scale_factor) OVERRIDE {
44    return base::FilePath();
45  }
46  virtual base::FilePath GetPathForLocalePack(
47      const base::FilePath& pack_path,
48      const std::string& locale) OVERRIDE {
49    return base::FilePath();
50  }
51  virtual gfx::Image GetImageNamed(int resource_id) OVERRIDE {
52    last_resource_id_ = resource_id;
53    switch (resource_id) {
54      case IDR_WINDOW_BUBBLE_SHADOW_SMALL:
55        return image_small_;
56      case IDR_AURA_SHADOW_ACTIVE:
57      case IDR_AURA_SHADOW_INACTIVE:
58        return image_large_;
59      default:
60        NOTREACHED();
61        return gfx::Image();
62    }
63  }
64  virtual gfx::Image GetNativeImageNamed(
65      int resource_id, ui::ResourceBundle::ImageRTL rtl) OVERRIDE {
66    return gfx::Image();
67  }
68  virtual base::RefCountedStaticMemory* LoadDataResourceBytes(
69      int resource_id, ui::ScaleFactor scale_factor) OVERRIDE {
70    return NULL;
71  }
72  virtual bool GetRawDataResource(
73      int resource_id, ui::ScaleFactor scale_factor,
74      base::StringPiece* value) OVERRIDE {
75    return false;
76  }
77  virtual bool GetLocalizedString(
78      int message_id, base::string16* value) OVERRIDE {
79    return false;
80  }
81  virtual scoped_ptr<gfx::Font> GetFont(
82      ui::ResourceBundle::FontStyle style) OVERRIDE {
83    return scoped_ptr<gfx::Font>();
84  }
85
86  int last_resource_id() const { return last_resource_id_; }
87
88 private:
89  gfx::Image image_small_;
90  gfx::Image image_large_;
91  int last_resource_id_;
92
93  DISALLOW_COPY_AND_ASSIGN(MockResourceBundleDelegate);
94};
95
96}  // namespace
97
98class ShadowTest: public aura::test::AuraTestBase {
99 public:
100  ShadowTest() {}
101  virtual ~ShadowTest() {}
102
103  MockResourceBundleDelegate* delegate() { return delegate_.get(); }
104
105  // aura::testAuraBase:
106  virtual void SetUp() OVERRIDE {
107    aura::test::AuraTestBase::SetUp();
108    delegate_.reset(new MockResourceBundleDelegate());
109    if (ResourceBundle::HasSharedInstance())
110      ui::ResourceBundle::CleanupSharedInstance();
111    ui::ResourceBundle::InitSharedInstanceWithLocale(
112        "en-US", delegate(), ui::ResourceBundle::LOAD_COMMON_RESOURCES);
113  }
114  virtual void TearDown() OVERRIDE {
115    ui::ResourceBundle::CleanupSharedInstance();
116    base::FilePath ui_test_pak_path;
117    ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
118    ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
119    aura::test::AuraTestBase::TearDown();
120  }
121 private:
122  scoped_ptr<MockResourceBundleDelegate> delegate_;
123  DISALLOW_COPY_AND_ASSIGN(ShadowTest);
124};
125
126// Test if the proper image is set for the specified style.
127TEST_F(ShadowTest, UpdateImagesForStyle) {
128  Shadow shadow;
129
130  shadow.Init(Shadow::STYLE_SMALL);
131  EXPECT_EQ(delegate()->last_resource_id(), IDR_WINDOW_BUBBLE_SHADOW_SMALL);
132  shadow.SetStyle(Shadow::STYLE_ACTIVE);
133  EXPECT_EQ(delegate()->last_resource_id(), IDR_AURA_SHADOW_ACTIVE);
134  shadow.SetStyle(Shadow::STYLE_INACTIVE);
135  EXPECT_EQ(delegate()->last_resource_id(), IDR_AURA_SHADOW_INACTIVE);
136}
137
138// Test if the proper content bounds is calculated based on the current style.
139TEST_F(ShadowTest, SetContentBounds) {
140  Shadow shadow;
141
142  // Verify that layer bounds are inset from content bounds.
143  shadow.Init(Shadow::STYLE_ACTIVE);
144  gfx::Rect content_bounds(100, 100, 300, 300);
145  shadow.SetContentBounds(content_bounds);
146  EXPECT_EQ(shadow.content_bounds(), content_bounds);
147  EXPECT_EQ(shadow.layer()->bounds(), gfx::Rect(36, 36, 428, 428));
148
149  shadow.SetStyle(Shadow::STYLE_SMALL);
150  EXPECT_EQ(shadow.content_bounds(), content_bounds);
151  EXPECT_EQ(shadow.layer()->bounds(), gfx::Rect(96, 96, 308, 308));
152}
153}  // namespace wm
154