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 "ui/views/corewm/window_util.h"
6
7#include "ui/aura/root_window.h"
8#include "ui/aura/test/aura_test_base.h"
9#include "ui/aura/window.h"
10#include "ui/compositor/test/test_layers.h"
11#include "ui/views/view_constants_aura.h"
12#include "ui/views/widget/widget.h"
13
14class WindowUtilTest : public aura::test::AuraTestBase {
15 public:
16  WindowUtilTest() {
17  }
18
19  virtual ~WindowUtilTest() {
20  }
21
22  // Creates a widget of TYPE_CONTROL.
23  // The caller takes ownership of the returned widget.
24  views::Widget* CreateControlWidget(
25      aura::Window* parent,
26      const gfx::Rect& bounds) const WARN_UNUSED_RESULT {
27    views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
28    params.parent = parent;
29    params.bounds = bounds;
30    views::Widget* widget = new views::Widget();
31    widget->Init(params);
32    return widget;
33  }
34
35  // Returns a view with a layer with the passed in |bounds| and |layer_name|.
36  // The caller takes ownership of the returned view.
37  views::View* CreateViewWithLayer(
38      const gfx::Rect& bounds,
39      const char* layer_name) const WARN_UNUSED_RESULT {
40    views::View* view = new views::View();
41    view->SetBoundsRect(bounds);
42    view->SetPaintToLayer(true);
43    view->layer()->set_name(layer_name);
44    return view;
45  }
46
47 private:
48  DISALLOW_COPY_AND_ASSIGN(WindowUtilTest);
49};
50
51// Test that RecreateWindowLayers() recreates the layers for all child windows
52// and all child views and that the z-order of the recreated layers matches that
53// of the original layers.
54// Test hierarchy:
55// w1
56// +-- v1
57// +-- v2 (no layer)
58//     +-- v3 (no layer)
59//     +-- v4
60// +-- w2
61//     +-- v5
62//         +-- v6
63// +-- v7
64TEST_F(WindowUtilTest, RecreateWindowLayers) {
65  views::Widget* w1 = CreateControlWidget(root_window(),
66                                          gfx::Rect(0, 0, 100, 100));
67  w1->GetNativeView()->layer()->set_name("w1");
68
69  views::View* v2 = new views::View();
70  v2->SetBounds(0, 1, 100, 101);
71  views::View* v3 = new views::View();
72  v3->SetBounds(0, 2, 100, 102);
73  views::View* w2_host_view = new views::View();
74
75  w1->GetRootView()->AddChildView(CreateViewWithLayer(
76      gfx::Rect(0, 3, 100, 103), "v1"));
77  w1->GetRootView()->AddChildView(v2);
78  v2->AddChildView(v3);
79  v2->AddChildView(CreateViewWithLayer(gfx::Rect(0, 4, 100, 104), "v4"));
80
81  w1->GetRootView()->AddChildView(w2_host_view);
82  w1->GetRootView()->AddChildView(CreateViewWithLayer(
83      gfx::Rect(0, 4, 100, 104), "v7"));
84
85  views::Widget* w2 = CreateControlWidget(w1->GetNativeView(),
86                                          gfx::Rect(0, 5, 100, 105));
87  w2->GetNativeView()->layer()->set_name("w2");
88  w2->GetNativeView()->SetProperty(views::kHostViewKey, w2_host_view);
89
90  views::View* v5 = CreateViewWithLayer(gfx::Rect(0, 6, 100, 106), "v5");
91  w2->GetRootView()->AddChildView(v5);
92  v5->AddChildView(CreateViewWithLayer(gfx::Rect(0, 7, 100, 107), "v6"));
93
94  // Test the initial order of the layers.
95  ui::Layer* w1_layer = w1->GetNativeView()->layer();
96  ASSERT_EQ("w1", w1_layer->name());
97  ASSERT_EQ("v1 v4 w2 v7", ui::test::ChildLayerNamesAsString(*w1_layer));
98  ui::Layer* w2_layer = w1_layer->children()[2];
99  ASSERT_EQ("v5", ui::test::ChildLayerNamesAsString(*w2_layer));
100  ui::Layer* v5_layer = w2_layer->children()[0];
101  ASSERT_EQ("v6", ui::test::ChildLayerNamesAsString(*v5_layer));
102
103  w1_layer = views::corewm::RecreateWindowLayers(w1->GetNativeView(), false);
104
105  // The order of the layers returned by RecreateWindowLayers() should match the
106  // order of the layers prior to calling RecreateWindowLayers().
107  ASSERT_EQ("w1", w1_layer->name());
108  ASSERT_EQ("v1 v4 w2 v7", ui::test::ChildLayerNamesAsString(*w1_layer));
109  w2_layer = w1_layer->children()[2];
110  ASSERT_EQ("v5", ui::test::ChildLayerNamesAsString(*w2_layer));
111  v5_layer = w2_layer->children()[0];
112  ASSERT_EQ("v6", ui::test::ChildLayerNamesAsString(*v5_layer));
113
114  views::corewm::DeepDeleteLayers(w1_layer);
115  // The views and the widgets are destroyed when AuraTestHelper::TearDown()
116  // destroys root_window().
117}
118