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/views/view.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "ui/aura/window.h"
9 #include "ui/compositor/layer.h"
10 #include "ui/compositor/layer_tree_owner.h"
11 #include "ui/compositor/test/test_layers.h"
12 #include "ui/gfx/geometry/rect.h"
13 #include "ui/views/test/views_test_base.h"
14 #include "ui/views/view_constants_aura.h"
15 #include "ui/views/widget/widget.h"
16 #include "ui/wm/core/window_util.h"
17
18 namespace views {
19
20 namespace {
21
22 // Creates a widget of TYPE_CONTROL.
23 // The caller takes ownership of the returned widget.
CreateControlWidget(aura::Window * parent,const gfx::Rect & bounds)24 Widget* CreateControlWidget(aura::Window* parent, const gfx::Rect& bounds) {
25 Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
26 params.parent = parent;
27 params.bounds = bounds;
28 Widget* widget = new Widget();
29 widget->Init(params);
30 return widget;
31 }
32
33 // Returns a view with a layer with the passed in |bounds| and |layer_name|.
34 // The caller takes ownership of the returned view.
CreateViewWithLayer(const gfx::Rect & bounds,const char * layer_name)35 View* CreateViewWithLayer(const gfx::Rect& bounds, const char* layer_name) {
36 View* view = new View();
37 view->SetBoundsRect(bounds);
38 view->SetPaintToLayer(true);
39 view->layer()->set_name(layer_name);
40 return view;
41 }
42
43 } // namespace
44
45 typedef ViewsTestBase ViewAuraTest;
46
47 // Test that wm::RecreateLayers() recreates the layers for all child windows and
48 // all child views and that the z-order of the recreated layers matches that of
49 // the original layers.
50 // Test hierarchy:
51 // w1
52 // +-- v1
53 // +-- v2 (no layer)
54 // +-- v3 (no layer)
55 // +-- v4
56 // +-- w2
57 // +-- v5
58 // +-- v6
59 // +-- v7
60 // +-- v8
61 // +-- v9
TEST_F(ViewAuraTest,RecreateLayersWithWindows)62 TEST_F(ViewAuraTest, RecreateLayersWithWindows) {
63 Widget* w1 = CreateControlWidget(GetContext(), gfx::Rect(0, 0, 100, 100));
64 w1->GetNativeView()->layer()->set_name("w1");
65
66 View* v2 = new View();
67 v2->SetBounds(0, 1, 100, 101);
68 View* v3 = new View();
69 v3->SetBounds(0, 2, 100, 102);
70 View* w2_host_view = new View();
71
72 View* v1 = CreateViewWithLayer(gfx::Rect(0, 3, 100, 103), "v1");
73 ui::Layer* v1_layer = v1->layer();
74 w1->GetRootView()->AddChildView(v1);
75 w1->GetRootView()->AddChildView(v2);
76 v2->AddChildView(v3);
77 View* v4 = CreateViewWithLayer(gfx::Rect(0, 4, 100, 104), "v4");
78 ui::Layer* v4_layer = v4->layer();
79 v2->AddChildView(v4);
80
81 w1->GetRootView()->AddChildView(w2_host_view);
82 View* v7 = CreateViewWithLayer(gfx::Rect(0, 4, 100, 104), "v7");
83 ui::Layer* v7_layer = v7->layer();
84 w1->GetRootView()->AddChildView(v7);
85
86 View* v8 = CreateViewWithLayer(gfx::Rect(0, 4, 100, 104), "v8");
87 ui::Layer* v8_layer = v8->layer();
88 v7->AddChildView(v8);
89
90 View* v9 = CreateViewWithLayer(gfx::Rect(0, 4, 100, 104), "v9");
91 ui::Layer* v9_layer = v9->layer();
92 v7->AddChildView(v9);
93
94 Widget* w2 =
95 CreateControlWidget(w1->GetNativeView(), gfx::Rect(0, 5, 100, 105));
96 w2->GetNativeView()->layer()->set_name("w2");
97 w2->GetNativeView()->SetProperty(kHostViewKey, w2_host_view);
98
99 View* v5 = CreateViewWithLayer(gfx::Rect(0, 6, 100, 106), "v5");
100 w2->GetRootView()->AddChildView(v5);
101 View* v6 = CreateViewWithLayer(gfx::Rect(0, 7, 100, 107), "v6");
102 ui::Layer* v6_layer = v6->layer();
103 v5->AddChildView(v6);
104
105 // Test the initial order of the layers.
106 ui::Layer* w1_layer = w1->GetNativeView()->layer();
107 ASSERT_EQ("w1", w1_layer->name());
108 ASSERT_EQ("v1 v4 w2 v7", ui::test::ChildLayerNamesAsString(*w1_layer));
109 ui::Layer* w2_layer = w1_layer->children()[2];
110 ASSERT_EQ("v5", ui::test::ChildLayerNamesAsString(*w2_layer));
111 ui::Layer* v5_layer = w2_layer->children()[0];
112 ASSERT_EQ("v6", ui::test::ChildLayerNamesAsString(*v5_layer));
113
114 {
115 scoped_ptr<ui::LayerTreeOwner> cloned_owner(
116 wm::RecreateLayers(w1->GetNativeView()));
117 EXPECT_EQ(w1_layer, cloned_owner->root());
118 EXPECT_NE(w1_layer, w1->GetNativeView()->layer());
119
120 // The old layers should still exist and have the same hierarchy.
121 ASSERT_EQ("w1", w1_layer->name());
122 ASSERT_EQ("v1 v4 w2 v7", ui::test::ChildLayerNamesAsString(*w1_layer));
123 ASSERT_EQ("v5", ui::test::ChildLayerNamesAsString(*w2_layer));
124 ASSERT_EQ("v6", ui::test::ChildLayerNamesAsString(*v5_layer));
125 EXPECT_EQ("v8 v9", ui::test::ChildLayerNamesAsString(*v7_layer));
126
127 ASSERT_EQ(4u, w1_layer->children().size());
128 EXPECT_EQ(v1_layer, w1_layer->children()[0]);
129 EXPECT_EQ(v4_layer, w1_layer->children()[1]);
130 EXPECT_EQ(w2_layer, w1_layer->children()[2]);
131 EXPECT_EQ(v7_layer, w1_layer->children()[3]);
132
133 ASSERT_EQ(1u, w2_layer->children().size());
134 EXPECT_EQ(v5_layer, w2_layer->children()[0]);
135
136 ASSERT_EQ(1u, v5_layer->children().size());
137 EXPECT_EQ(v6_layer, v5_layer->children()[0]);
138
139 ASSERT_EQ(0u, v6_layer->children().size());
140
141 EXPECT_EQ(2u, v7_layer->children().size());
142 EXPECT_EQ(v8_layer, v7_layer->children()[0]);
143 EXPECT_EQ(v9_layer, v7_layer->children()[1]);
144
145 // The cloned layers should have the same hierarchy as old.
146 ui::Layer* w1_new_layer = w1->GetNativeView()->layer();
147 EXPECT_EQ("w1", w1_new_layer->name());
148 ASSERT_EQ("v1 v4 w2 v7", ui::test::ChildLayerNamesAsString(*w1_new_layer));
149 ui::Layer* w2_new_layer = w1_new_layer->children()[2];
150 ASSERT_EQ("v5", ui::test::ChildLayerNamesAsString(*w2_new_layer));
151 ui::Layer* v5_new_layer = w2_new_layer->children()[0];
152 ASSERT_EQ("v6", ui::test::ChildLayerNamesAsString(*v5_new_layer));
153 ui::Layer* v7_new_layer = w1_new_layer->children()[3];
154 ASSERT_EQ("v8 v9", ui::test::ChildLayerNamesAsString(*v7_new_layer));
155 }
156 // The views and the widgets are destroyed when AuraTestHelper::TearDown()
157 // destroys root_window().
158 }
159
160 } // namespace views
161