|  | // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "components/exo/sub_surface.h" | 
|  |  | 
|  | #include "base/memory/ptr_util.h" | 
|  | #include "components/exo/surface.h" | 
|  | #include "components/exo/test/exo_test_base.h" | 
|  | #include "components/exo/test/exo_test_helper.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | namespace exo { | 
|  | namespace { | 
|  |  | 
|  | using SubSurfaceTest = test::ExoTestBase; | 
|  |  | 
|  | TEST_F(SubSurfaceTest, SetPosition) { | 
|  | std::unique_ptr<Surface> parent(new Surface); | 
|  | std::unique_ptr<Surface> surface(new Surface); | 
|  | std::unique_ptr<SubSurface> sub_surface( | 
|  | new SubSurface(surface.get(), parent.get())); | 
|  |  | 
|  | // Initial position is at the origin. | 
|  | EXPECT_EQ(gfx::Point().ToString(), | 
|  | surface->window()->bounds().origin().ToString()); | 
|  |  | 
|  | // Set position to 10, 10. | 
|  | gfx::Point position(10, 10); | 
|  | sub_surface->SetPosition(position); | 
|  |  | 
|  | // A call to Commit() is required for position to take effect. | 
|  | EXPECT_EQ(gfx::Point().ToString(), | 
|  | surface->window()->bounds().origin().ToString()); | 
|  |  | 
|  | // Check that position is updated when Commit() is called. | 
|  | parent->Commit(); | 
|  | EXPECT_EQ(position.ToString(), | 
|  | surface->window()->bounds().origin().ToString()); | 
|  |  | 
|  | // Create and commit a new sub-surface using the same surface. | 
|  | sub_surface.reset(); | 
|  | sub_surface = base::MakeUnique<SubSurface>(surface.get(), parent.get()); | 
|  | parent->Commit(); | 
|  |  | 
|  | // Initial position should be reset to origin. | 
|  | EXPECT_EQ(gfx::Point().ToString(), | 
|  | surface->window()->bounds().origin().ToString()); | 
|  | } | 
|  |  | 
|  | TEST_F(SubSurfaceTest, PlaceAbove) { | 
|  | std::unique_ptr<Surface> parent(new Surface); | 
|  | std::unique_ptr<Surface> surface1(new Surface); | 
|  | std::unique_ptr<Surface> surface2(new Surface); | 
|  | std::unique_ptr<Surface> non_sibling_surface(new Surface); | 
|  | std::unique_ptr<SubSurface> sub_surface1( | 
|  | new SubSurface(surface1.get(), parent.get())); | 
|  | std::unique_ptr<SubSurface> sub_surface2( | 
|  | new SubSurface(surface2.get(), parent.get())); | 
|  |  | 
|  | ASSERT_EQ(2u, parent->window()->children().size()); | 
|  | EXPECT_EQ(surface1->window(), parent->window()->children()[0]); | 
|  | EXPECT_EQ(surface2->window(), parent->window()->children()[1]); | 
|  |  | 
|  | sub_surface2->PlaceAbove(parent.get()); | 
|  | sub_surface1->PlaceAbove(non_sibling_surface.get());  // Invalid | 
|  | sub_surface1->PlaceAbove(surface1.get());             // Invalid | 
|  | sub_surface1->PlaceAbove(surface2.get()); | 
|  |  | 
|  | // Nothing should have changed as Commit() is required for new stacking | 
|  | // order to take effect. | 
|  | EXPECT_EQ(surface1->window(), parent->window()->children()[0]); | 
|  | EXPECT_EQ(surface2->window(), parent->window()->children()[1]); | 
|  |  | 
|  | parent->Commit(); | 
|  |  | 
|  | // surface1 should now be stacked above surface2. | 
|  | EXPECT_EQ(surface2->window(), parent->window()->children()[0]); | 
|  | EXPECT_EQ(surface1->window(), parent->window()->children()[1]); | 
|  | } | 
|  |  | 
|  | TEST_F(SubSurfaceTest, PlaceBelow) { | 
|  | std::unique_ptr<Surface> parent(new Surface); | 
|  | std::unique_ptr<Surface> surface1(new Surface); | 
|  | std::unique_ptr<Surface> surface2(new Surface); | 
|  | std::unique_ptr<Surface> non_sibling_surface(new Surface); | 
|  | std::unique_ptr<SubSurface> sub_surface1( | 
|  | new SubSurface(surface1.get(), parent.get())); | 
|  | std::unique_ptr<SubSurface> sub_surface2( | 
|  | new SubSurface(surface2.get(), parent.get())); | 
|  |  | 
|  | ASSERT_EQ(2u, parent->window()->children().size()); | 
|  | EXPECT_EQ(surface1->window(), parent->window()->children()[0]); | 
|  | EXPECT_EQ(surface2->window(), parent->window()->children()[1]); | 
|  |  | 
|  | sub_surface2->PlaceBelow(parent.get());               // Invalid | 
|  | sub_surface2->PlaceBelow(non_sibling_surface.get());  // Invalid | 
|  | sub_surface1->PlaceBelow(surface2.get()); | 
|  | sub_surface2->PlaceBelow(surface1.get()); | 
|  |  | 
|  | // Nothing should have changed as Commit() is required for new stacking | 
|  | // order to take effect. | 
|  | EXPECT_EQ(surface1->window(), parent->window()->children()[0]); | 
|  | EXPECT_EQ(surface2->window(), parent->window()->children()[1]); | 
|  |  | 
|  | parent->Commit(); | 
|  |  | 
|  | // surface1 should now be stacked above surface2. | 
|  | EXPECT_EQ(surface2->window(), parent->window()->children()[0]); | 
|  | EXPECT_EQ(surface1->window(), parent->window()->children()[1]); | 
|  | } | 
|  |  | 
|  | TEST_F(SubSurfaceTest, SetCommitBehavior) { | 
|  | std::unique_ptr<Surface> parent(new Surface); | 
|  | std::unique_ptr<Surface> child(new Surface); | 
|  | std::unique_ptr<Surface> grandchild(new Surface); | 
|  | std::unique_ptr<SubSurface> child_sub_surface( | 
|  | new SubSurface(child.get(), parent.get())); | 
|  | std::unique_ptr<SubSurface> grandchild_sub_surface( | 
|  | new SubSurface(grandchild.get(), child.get())); | 
|  |  | 
|  | // Initial position is at the origin. | 
|  | EXPECT_EQ(gfx::Point().ToString(), | 
|  | grandchild->window()->bounds().origin().ToString()); | 
|  |  | 
|  | // Set position to 10, 10. | 
|  | gfx::Point position1(10, 10); | 
|  | grandchild_sub_surface->SetPosition(position1); | 
|  | child->Commit(); | 
|  |  | 
|  | // Initial commit behavior is synchronous and the effect of the child | 
|  | // Commit() call will not take effect until Commit() is called on the | 
|  | // parent. | 
|  | EXPECT_EQ(gfx::Point().ToString(), | 
|  | grandchild->window()->bounds().origin().ToString()); | 
|  |  | 
|  | parent->Commit(); | 
|  |  | 
|  | // Position should have been updated when Commit() has been called on both | 
|  | // child and parent. | 
|  | EXPECT_EQ(position1.ToString(), | 
|  | grandchild->window()->bounds().origin().ToString()); | 
|  |  | 
|  | // Disable synchronous commit behavior. | 
|  | bool synchronized = false; | 
|  | child_sub_surface->SetCommitBehavior(synchronized); | 
|  |  | 
|  | // Set position to 20, 20. | 
|  | gfx::Point position2(20, 20); | 
|  | grandchild_sub_surface->SetPosition(position2); | 
|  | child->Commit(); | 
|  |  | 
|  | // A Commit() call on child should be sufficient for the position of | 
|  | // grandchild to take effect when synchronous is disabled. | 
|  | EXPECT_EQ(position2.ToString(), | 
|  | grandchild->window()->bounds().origin().ToString()); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace exo |