| // 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 "base/message_loop/message_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "components/exo/buffer.h" |
| #include "components/exo/shell_surface.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" |
| #include "ui/aura/window.h" |
| #include "ui/base/hit_test.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/wm/core/window_util.h" |
| |
| namespace exo { |
| namespace { |
| |
| class ShellSurfaceTest : public test::ExoTestBase, |
| public ::testing::WithParamInterface<bool> { |
| void SetUp() override { |
| Surface::SetUseSurfaceLayer(GetParam()); |
| test::ExoTestBase::SetUp(); |
| } |
| }; |
| |
| uint32_t ConfigureFullscreen(uint32_t serial, |
| const gfx::Size& size, |
| ash::wm::WindowStateType state_type, |
| bool resizing, |
| bool activated) { |
| EXPECT_EQ(ash::wm::WINDOW_STATE_TYPE_FULLSCREEN, state_type); |
| return serial; |
| } |
| |
| TEST_P(ShellSurfaceTest, AcknowledgeConfigure) { |
| gfx::Size buffer_size(32, 32); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| |
| gfx::Point origin(100, 100); |
| shell_surface->GetWidget()->SetBounds(gfx::Rect(origin, buffer_size)); |
| EXPECT_EQ(origin.ToString(), |
| surface->GetBoundsInRootWindow().origin().ToString()); |
| |
| const uint32_t kSerial = 1; |
| shell_surface->set_configure_callback( |
| base::Bind(&ConfigureFullscreen, kSerial)); |
| shell_surface->SetFullscreen(true); |
| |
| // Surface origin should not change until configure request is acknowledged. |
| EXPECT_EQ(origin.ToString(), |
| surface->GetBoundsInRootWindow().origin().ToString()); |
| |
| shell_surface->AcknowledgeConfigure(kSerial); |
| std::unique_ptr<Buffer> fullscreen_buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer( |
| CurrentContext()->bounds().size()))); |
| surface->Attach(fullscreen_buffer.get()); |
| surface->Commit(); |
| |
| EXPECT_EQ(gfx::Point().ToString(), |
| surface->GetBoundsInRootWindow().origin().ToString()); |
| } |
| |
| TEST_P(ShellSurfaceTest, SetParent) { |
| gfx::Size buffer_size(256, 256); |
| std::unique_ptr<Buffer> parent_buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> parent_surface(new Surface); |
| std::unique_ptr<ShellSurface> parent_shell_surface( |
| new ShellSurface(parent_surface.get())); |
| |
| parent_surface->Attach(parent_buffer.get()); |
| parent_surface->Commit(); |
| |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| shell_surface->SetParent(parent_shell_surface.get()); |
| |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| EXPECT_EQ( |
| parent_shell_surface->GetWidget()->GetNativeWindow(), |
| wm::GetTransientParent(shell_surface->GetWidget()->GetNativeWindow())); |
| } |
| |
| TEST_P(ShellSurfaceTest, Maximize) { |
| gfx::Size buffer_size(256, 256); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| surface->Attach(buffer.get()); |
| shell_surface->Maximize(); |
| surface->Commit(); |
| EXPECT_EQ(CurrentContext()->bounds().width(), |
| shell_surface->GetWidget()->GetWindowBoundsInScreen().width()); |
| } |
| |
| TEST_P(ShellSurfaceTest, Minimize) { |
| gfx::Size buffer_size(256, 256); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| shell_surface->Minimize(); |
| EXPECT_TRUE(shell_surface->GetWidget()->IsMinimized()); |
| } |
| |
| TEST_P(ShellSurfaceTest, Restore) { |
| gfx::Size buffer_size(256, 256); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| // Note: Remove contents to avoid issues with maximize animations in tests. |
| if (!GetParam()) { |
| surface->Attach(nullptr); |
| surface->Commit(); |
| } |
| shell_surface->Maximize(); |
| shell_surface->Restore(); |
| EXPECT_EQ( |
| buffer_size.ToString(), |
| shell_surface->GetWidget()->GetWindowBoundsInScreen().size().ToString()); |
| } |
| |
| TEST_P(ShellSurfaceTest, SetFullscreen) { |
| gfx::Size buffer_size(256, 256); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| shell_surface->SetFullscreen(true); |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| EXPECT_EQ(CurrentContext()->bounds().ToString(), |
| shell_surface->GetWidget()->GetWindowBoundsInScreen().ToString()); |
| } |
| |
| TEST_P(ShellSurfaceTest, SetTitle) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| shell_surface->SetTitle(base::string16(base::ASCIIToUTF16("test"))); |
| surface->Commit(); |
| } |
| |
| TEST_P(ShellSurfaceTest, SetApplicationId) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| surface->Commit(); |
| EXPECT_EQ("", ShellSurface::GetApplicationId( |
| shell_surface->GetWidget()->GetNativeWindow())); |
| shell_surface->SetApplicationId("test"); |
| EXPECT_EQ("test", ShellSurface::GetApplicationId( |
| shell_surface->GetWidget()->GetNativeWindow())); |
| } |
| |
| TEST_P(ShellSurfaceTest, Move) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| // Map shell surface. |
| surface->Commit(); |
| |
| // The interactive move should end when surface is destroyed. |
| shell_surface->Move(); |
| |
| // Test that destroying the shell surface before move ends is OK. |
| shell_surface.reset(); |
| } |
| |
| TEST_P(ShellSurfaceTest, Resize) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| // Map shell surface. |
| surface->Commit(); |
| |
| // The interactive resize should end when surface is destroyed. |
| shell_surface->Resize(HTBOTTOMRIGHT); |
| |
| // Test that destroying the surface before resize ends is OK. |
| surface.reset(); |
| } |
| |
| TEST_P(ShellSurfaceTest, SetGeometry) { |
| gfx::Size buffer_size(64, 64); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| gfx::Rect geometry(16, 16, 32, 32); |
| shell_surface->SetGeometry(geometry); |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| EXPECT_EQ( |
| geometry.size().ToString(), |
| shell_surface->GetWidget()->GetWindowBoundsInScreen().size().ToString()); |
| EXPECT_EQ(gfx::Rect(gfx::Point() - geometry.OffsetFromOrigin(), buffer_size) |
| .ToString(), |
| surface->bounds().ToString()); |
| } |
| |
| TEST_P(ShellSurfaceTest, SetScale) { |
| gfx::Size buffer_size(64, 64); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| double scale = 1.5; |
| shell_surface->SetScale(scale); |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| |
| gfx::Transform transform; |
| transform.Scale(1.0 / scale, 1.0 / scale); |
| EXPECT_EQ(transform.ToString(), |
| surface->layer()->GetTargetTransform().ToString()); |
| } |
| |
| void Close(int* close_call_count) { |
| (*close_call_count)++; |
| } |
| |
| TEST_P(ShellSurfaceTest, CloseCallback) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| int close_call_count = 0; |
| shell_surface->set_close_callback( |
| base::Bind(&Close, base::Unretained(&close_call_count))); |
| |
| surface->Commit(); |
| |
| EXPECT_EQ(0, close_call_count); |
| shell_surface->GetWidget()->Close(); |
| EXPECT_EQ(1, close_call_count); |
| } |
| |
| void DestroyShellSurface(std::unique_ptr<ShellSurface>* shell_surface) { |
| shell_surface->reset(); |
| } |
| |
| TEST_P(ShellSurfaceTest, SurfaceDestroyedCallback) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| shell_surface->set_surface_destroyed_callback( |
| base::Bind(&DestroyShellSurface, base::Unretained(&shell_surface))); |
| |
| surface->Commit(); |
| |
| EXPECT_TRUE(shell_surface.get()); |
| surface.reset(); |
| EXPECT_FALSE(shell_surface.get()); |
| } |
| |
| uint32_t Configure(gfx::Size* suggested_size, |
| ash::wm::WindowStateType* has_state_type, |
| bool* is_resizing, |
| bool* is_active, |
| const gfx::Size& size, |
| ash::wm::WindowStateType state_type, |
| bool resizing, |
| bool activated) { |
| *suggested_size = size; |
| *has_state_type = state_type; |
| *is_resizing = resizing; |
| *is_active = activated; |
| return 0; |
| } |
| |
| TEST_P(ShellSurfaceTest, ConfigureCallback) { |
| std::unique_ptr<Surface> surface(new Surface); |
| std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); |
| |
| gfx::Size suggested_size; |
| ash::wm::WindowStateType has_state_type = ash::wm::WINDOW_STATE_TYPE_NORMAL; |
| bool is_resizing = false; |
| bool is_active = false; |
| shell_surface->set_configure_callback( |
| base::Bind(&Configure, base::Unretained(&suggested_size), |
| base::Unretained(&has_state_type), |
| base::Unretained(&is_resizing), base::Unretained(&is_active))); |
| shell_surface->Maximize(); |
| shell_surface->AcknowledgeConfigure(0); |
| EXPECT_EQ(CurrentContext()->bounds().width(), suggested_size.width()); |
| EXPECT_EQ(ash::wm::WINDOW_STATE_TYPE_MAXIMIZED, has_state_type); |
| shell_surface->Restore(); |
| shell_surface->AcknowledgeConfigure(0); |
| |
| shell_surface->SetFullscreen(true); |
| shell_surface->AcknowledgeConfigure(0); |
| EXPECT_EQ(CurrentContext()->bounds().size().ToString(), |
| suggested_size.ToString()); |
| EXPECT_EQ(ash::wm::WINDOW_STATE_TYPE_FULLSCREEN, has_state_type); |
| shell_surface->SetFullscreen(false); |
| shell_surface->AcknowledgeConfigure(0); |
| |
| gfx::Size buffer_size(64, 64); |
| std::unique_ptr<Buffer> buffer( |
| new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); |
| surface->Attach(buffer.get()); |
| surface->Commit(); |
| shell_surface->GetWidget()->Activate(); |
| shell_surface->AcknowledgeConfigure(0); |
| EXPECT_TRUE(is_active); |
| shell_surface->GetWidget()->Deactivate(); |
| shell_surface->AcknowledgeConfigure(0); |
| EXPECT_FALSE(is_active); |
| |
| EXPECT_FALSE(is_resizing); |
| shell_surface->Resize(HTBOTTOMRIGHT); |
| shell_surface->AcknowledgeConfigure(0); |
| EXPECT_TRUE(is_resizing); |
| } |
| |
| INSTANTIATE_TEST_CASE_P(, ShellSurfaceTest, ::testing::Bool()); |
| |
| } // namespace |
| } // namespace exo |