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 18namespace views { 19 20namespace { 21 22// Creates a widget of TYPE_CONTROL. 23// The caller takes ownership of the returned widget. 24Widget* 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. 35View* 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 45typedef 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 62TEST_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