// Copyright 2014 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 "ash/wm/tablet_mode/tablet_mode_window_manager.h"

#include <string>

#include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/shelf_prefs.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/cpp/window_state_type.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/session/session_controller.h"
#include "ash/session/test_session_controller_client.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/shell_test_api.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/switchable_windows.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_resizer.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_observer.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "services/ui/public/interfaces/window_tree_constants.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h"

namespace ash {

// A helper function to set the shelf auto-hide preference. This has the same
// effect as the user toggling the shelf context menu option.
void SetShelfAutoHideBehaviorPref(int64_t display_id,
                                  ShelfAutoHideBehavior behavior) {
  PrefService* prefs =
      Shell::Get()->session_controller()->GetLastActiveUserPrefService();
  if (!prefs)
    return;
  SetShelfAutoHideBehaviorPref(prefs, display_id, behavior);
}

class TabletModeWindowManagerTest : public AshTestBase {
 public:
  TabletModeWindowManagerTest() = default;
  ~TabletModeWindowManagerTest() override = default;

  // Initialize parameters for test windows.  If |can_maximize| is not
  // set, |max_size| is the upper limiting size for the window,
  // whereas an empty size means that there is no limit.
  struct InitParams {
    InitParams(aura::client::WindowType t) : type(t) {}

    aura::client::WindowType type = aura::client::WINDOW_TYPE_NORMAL;
    gfx::Rect bounds;
    gfx::Size max_size;
    bool can_maximize = true;
    bool can_resize = true;
    bool show_on_creation = true;
  };

  // Creates a window which has a fixed size.
  aura::Window* CreateFixedSizeNonMaximizableWindow(
      aura::client::WindowType type,
      const gfx::Rect& bounds) {
    InitParams params(type);
    params.bounds = bounds;
    params.can_maximize = false;
    params.can_resize = false;
    return CreateWindowInWatchedContainer(params);
  }

  // Creates a window which can not be maximized, but resized. |max_size|
  // denotes the maximal possible size, if the size is empty, the window has no
  // upper limit. Note: This function will only work with a single root window.
  aura::Window* CreateNonMaximizableWindow(aura::client::WindowType type,
                                           const gfx::Rect& bounds,
                                           const gfx::Size& max_size) {
    InitParams params(type);
    params.bounds = bounds;
    params.max_size = max_size;
    params.can_maximize = false;
    return CreateWindowInWatchedContainer(params);
  }

  // Creates a maximizable and resizable window.
  aura::Window* CreateWindow(aura::client::WindowType type,
                             const gfx::Rect bounds) {
    InitParams params(type);
    params.bounds = bounds;
    return CreateWindowInWatchedContainer(params);
  }

  // Creates a window which also has a widget.
  aura::Window* CreateWindowWithWidget(const gfx::Rect& bounds) {
    // Note: The widget will get deleted with the window.
    views::Widget* widget = new views::Widget();
    views::Widget::InitParams params;
    params.context = CurrentContext();
    widget->Init(params);
    widget->Show();
    aura::Window* window = widget->GetNativeWindow();
    window->SetBounds(bounds);
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);

    return window;
  }

  // Create the tablet mode window manager.
  TabletModeWindowManager* CreateTabletModeWindowManager() {
    EXPECT_FALSE(tablet_mode_window_manager());
    Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
    return tablet_mode_window_manager();
  }

  // Destroy the tablet mode window manager.
  void DestroyTabletModeWindowManager() {
    Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(
        false);
    EXPECT_FALSE(tablet_mode_window_manager());
  }

  // Get the tablet window manager.
  TabletModeWindowManager* tablet_mode_window_manager() {
    return Shell::Get()
        ->tablet_mode_controller()
        ->tablet_mode_window_manager_.get();
  }

  // Resize our desktop.
  void ResizeDesktop(int width_delta) {
    gfx::Size size =
        display::Screen::GetScreen()
            ->GetDisplayNearestWindow(Shell::GetPrimaryRootWindow())
            .size();
    size.Enlarge(0, width_delta);
    UpdateDisplay(size.ToString());
  }

  // Create a window in one of the containers which are watched by the
  // TabletModeWindowManager. Note that this only works with one root window.
  aura::Window* CreateWindowInWatchedContainer(const InitParams& params) {
    aura::test::TestWindowDelegate* delegate = NULL;
    if (!params.can_maximize) {
      delegate = aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate();
      delegate->set_window_component(HTCAPTION);
      if (!params.max_size.IsEmpty())
        delegate->set_maximum_size(params.max_size);
    }
    aura::Window* window = aura::test::CreateTestWindowWithDelegateAndType(
        delegate, params.type, 0, params.bounds, NULL, params.show_on_creation);
    int32_t behavior = ui::mojom::kResizeBehaviorNone;
    behavior |= params.can_resize ? ui::mojom::kResizeBehaviorCanResize : 0;
    behavior |= params.can_maximize ? ui::mojom::kResizeBehaviorCanMaximize : 0;
    window->SetProperty(aura::client::kResizeBehaviorKey, behavior);
    aura::Window* container = Shell::GetContainer(
        Shell::GetPrimaryRootWindow(), wm::kSwitchableWindowContainerIds[0]);
    container->AddChild(window);
    return window;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TabletModeWindowManagerTest);
};

// Test that creating the object and destroying it without any windows should
// not cause any problems.
TEST_F(TabletModeWindowManagerTest, SimpleStart) {
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
  DestroyTabletModeWindowManager();
}

// Test that existing windows will handled properly when going into tablet
// mode.
TEST_F(TabletModeWindowManagerTest, PreCreateWindows) {
  // Bounds for windows we know can be controlled.
  gfx::Rect rect1(10, 10, 200, 50);
  gfx::Rect rect2(10, 60, 200, 50);
  gfx::Rect rect3(20, 140, 100, 100);
  // Bounds for anything else.
  gfx::Rect rect(80, 90, 100, 110);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
  std::unique_ptr<aura::Window> w2(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
  std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect3));
  std::unique_ptr<aura::Window> w4(
      CreateWindow(aura::client::WINDOW_TYPE_PANEL, rect));
  std::unique_ptr<aura::Window> w5(
      CreateWindow(aura::client::WINDOW_TYPE_POPUP, rect));
  std::unique_ptr<aura::Window> w6(
      CreateWindow(aura::client::WINDOW_TYPE_CONTROL, rect));
  std::unique_ptr<aura::Window> w7(
      CreateWindow(aura::client::WINDOW_TYPE_MENU, rect));
  std::unique_ptr<aura::Window> w8(
      CreateWindow(aura::client::WINDOW_TYPE_TOOLTIP, rect));
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
  EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());

  // Create the manager and make sure that all qualifying windows were detected
  // and changed.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_TRUE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_NE(rect3.origin().ToString(), w3->bounds().origin().ToString());
  EXPECT_EQ(rect3.size().ToString(), w3->bounds().size().ToString());

  // All other windows should not have been touched.
  EXPECT_FALSE(wm::GetWindowState(w4.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w5.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w6.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w7.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w8.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w7->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w8->bounds().ToString());

  // Destroy the manager again and check that the windows return to their
  // previous state.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
  EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w7->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w8->bounds().ToString());
}

// The same test as the above but while a system modal dialog is shown.
TEST_F(TabletModeWindowManagerTest, GoingToMaximizedWithModalDialogPresent) {
  // Bounds for windows we know can be controlled.
  gfx::Rect rect1(10, 10, 200, 50);
  gfx::Rect rect2(10, 60, 200, 50);
  gfx::Rect rect3(20, 140, 100, 100);
  // Bounds for anything else.
  gfx::Rect rect(80, 90, 100, 110);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
  std::unique_ptr<aura::Window> w2(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
  std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect3));
  std::unique_ptr<aura::Window> w4(
      CreateWindow(aura::client::WINDOW_TYPE_PANEL, rect));
  std::unique_ptr<aura::Window> w5(
      CreateWindow(aura::client::WINDOW_TYPE_POPUP, rect));
  std::unique_ptr<aura::Window> w6(
      CreateWindow(aura::client::WINDOW_TYPE_CONTROL, rect));
  std::unique_ptr<aura::Window> w7(
      CreateWindow(aura::client::WINDOW_TYPE_MENU, rect));
  std::unique_ptr<aura::Window> w8(
      CreateWindow(aura::client::WINDOW_TYPE_TOOLTIP, rect));
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
  EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());

  // Enable system modal dialog, and make sure both shelves are still hidden.
  ShellTestApi().SimulateModalWindowOpenForTest(true);
  EXPECT_TRUE(Shell::IsSystemModalWindowOpen());

  // Create the manager and make sure that all qualifying windows were detected
  // and changed.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_TRUE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_NE(rect3.origin().ToString(), w3->bounds().origin().ToString());
  EXPECT_EQ(rect3.size().ToString(), w3->bounds().size().ToString());

  // All other windows should not have been touched.
  EXPECT_FALSE(wm::GetWindowState(w4.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w5.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w6.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w7.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w8.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w7->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w8->bounds().ToString());

  // Destroy the manager again and check that the windows return to their
  // previous state.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
  EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w7->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w8->bounds().ToString());
}

// Test that non-maximizable windows get properly handled when going into
// tablet mode.
TEST_F(TabletModeWindowManagerTest,
       PreCreateNonMaximizableButResizableWindows) {
  // The window bounds.
  gfx::Rect rect(10, 10, 200, 50);
  gfx::Size max_size(300, 200);
  gfx::Size empty_size;
  std::unique_ptr<aura::Window> unlimited_window(CreateNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect, empty_size));
  std::unique_ptr<aura::Window> limited_window(CreateNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect, max_size));
  std::unique_ptr<aura::Window> fixed_window(
      CreateFixedSizeNonMaximizableWindow(aura::client::WINDOW_TYPE_NORMAL,
                                          rect));
  EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
  EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
  EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());

  gfx::Size workspace_size =
      screen_util::GetMaximizedWindowBoundsInParent(unlimited_window.get())
          .size();

  // Create the manager and make sure that all qualifying windows were detected
  // and changed.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  // The unlimited window should have the size of the workspace / parent window.
  EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
  EXPECT_EQ("0,0", unlimited_window->bounds().origin().ToString());
  EXPECT_EQ(workspace_size.ToString(),
            unlimited_window->bounds().size().ToString());
  // The limited window should have the size of the upper possible bounds.
  EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
  EXPECT_NE(rect.origin().ToString(),
            limited_window->bounds().origin().ToString());
  EXPECT_EQ(max_size.ToString(), limited_window->bounds().size().ToString());
  // The fixed size window should have the size of the original window.
  EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
  EXPECT_NE(rect.origin().ToString(),
            fixed_window->bounds().origin().ToString());
  EXPECT_EQ(rect.size().ToString(), fixed_window->bounds().size().ToString());

  // Destroy the manager again and check that the windows return to their
  // previous state.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
  EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
  EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
}

// Test that creating windows while a maximizer exists picks them properly up.
TEST_F(TabletModeWindowManagerTest, CreateWindows) {
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());

  // Create the windows and see that the window manager picks them up.
  // Rects for windows we know can be controlled.
  gfx::Rect rect1(10, 10, 200, 50);
  gfx::Rect rect2(10, 60, 200, 50);
  gfx::Rect rect3(20, 140, 100, 100);
  // One rect for anything else.
  gfx::Rect rect(80, 90, 100, 110);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
  std::unique_ptr<aura::Window> w2(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
  std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect3));
  std::unique_ptr<aura::Window> w4(
      CreateWindow(aura::client::WINDOW_TYPE_PANEL, rect));
  std::unique_ptr<aura::Window> w5(
      CreateWindow(aura::client::WINDOW_TYPE_POPUP, rect));
  std::unique_ptr<aura::Window> w6(
      CreateWindow(aura::client::WINDOW_TYPE_CONTROL, rect));
  std::unique_ptr<aura::Window> w7(
      CreateWindow(aura::client::WINDOW_TYPE_MENU, rect));
  std::unique_ptr<aura::Window> w8(
      CreateWindow(aura::client::WINDOW_TYPE_TOOLTIP, rect));
  EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_TRUE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());

  // Make sure that the position of the unresizable window is in the middle of
  // the screen.
  gfx::Size work_area_size =
      screen_util::GetDisplayWorkAreaBoundsInParent(w3.get()).size();
  gfx::Point center =
      gfx::Point((work_area_size.width() - rect3.size().width()) / 2,
                 (work_area_size.height() - rect3.size().height()) / 2);
  gfx::Rect centered_window_bounds = gfx::Rect(center, rect3.size());
  EXPECT_EQ(centered_window_bounds.ToString(), w3->bounds().ToString());

  // All other windows should not have been touched.
  EXPECT_FALSE(wm::GetWindowState(w4.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w5.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w6.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w7.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w8.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w7->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w8->bounds().ToString());

  // After the tablet mode was disabled all windows fall back into the mode
  // they were created for.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
  EXPECT_EQ(rect3.ToString(), w3->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w4->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w5->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w6->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w7->bounds().ToString());
  EXPECT_EQ(rect.ToString(), w8->bounds().ToString());
}

// Test that a window which got created while the tablet mode window manager
// is active gets restored to a usable (non tiny) size upon switching back.
TEST_F(TabletModeWindowManagerTest,
       CreateWindowInMaximizedModeRestoresToUsefulSize) {
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());

  // We pass in an empty rectangle to simulate a window creation with no
  // particular size.
  gfx::Rect empty_rect(0, 0, 0, 0);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, empty_rect));
  EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized());
  EXPECT_NE(empty_rect.ToString(), window->bounds().ToString());
  gfx::Rect maximized_size = window->bounds();

  // Destroy the tablet mode and check that the resulting size of the window
  // is remaining as it is (but not maximized).
  DestroyTabletModeWindowManager();

  EXPECT_FALSE(wm::GetWindowState(window.get())->IsMaximized());
  EXPECT_EQ(maximized_size.ToString(), window->bounds().ToString());
}

// Test that non-maximizable windows get properly handled when created in
// tablet mode.
TEST_F(TabletModeWindowManagerTest, CreateNonMaximizableButResizableWindows) {
  // Create the manager and make sure that all qualifying windows were detected
  // and changed.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);

  gfx::Rect rect(10, 10, 200, 50);
  gfx::Size max_size(300, 200);
  gfx::Size empty_size;
  std::unique_ptr<aura::Window> unlimited_window(CreateNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect, empty_size));
  std::unique_ptr<aura::Window> limited_window(CreateNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect, max_size));
  std::unique_ptr<aura::Window> fixed_window(
      CreateFixedSizeNonMaximizableWindow(aura::client::WINDOW_TYPE_NORMAL,
                                          rect));

  gfx::Size workspace_size =
      screen_util::GetMaximizedWindowBoundsInParent(unlimited_window.get())
          .size();

  // All windows should be sized now as big as possible and be centered.
  EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  // The unlimited window should have the size of the workspace / parent window.
  EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
  EXPECT_EQ("0,0", unlimited_window->bounds().origin().ToString());
  EXPECT_EQ(workspace_size.ToString(),
            unlimited_window->bounds().size().ToString());
  // The limited window should have the size of the upper possible bounds.
  EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
  EXPECT_NE(rect.origin().ToString(),
            limited_window->bounds().origin().ToString());
  EXPECT_EQ(max_size.ToString(), limited_window->bounds().size().ToString());
  // The fixed size window should have the size of the original window.
  EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
  EXPECT_NE(rect.origin().ToString(),
            fixed_window->bounds().origin().ToString());
  EXPECT_EQ(rect.size().ToString(), fixed_window->bounds().size().ToString());

  // Destroy the manager again and check that the windows return to their
  // creation state.
  DestroyTabletModeWindowManager();

  EXPECT_FALSE(wm::GetWindowState(unlimited_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), unlimited_window->bounds().ToString());
  EXPECT_FALSE(wm::GetWindowState(limited_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), limited_window->bounds().ToString());
  EXPECT_FALSE(wm::GetWindowState(fixed_window.get())->IsMaximized());
  EXPECT_EQ(rect.ToString(), fixed_window->bounds().ToString());
}

// Create a string which consists of the bounds and the state for comparison.
std::string GetPlacementString(const gfx::Rect& bounds,
                               ui::WindowShowState state) {
  return bounds.ToString() + base::StringPrintf(" %d", state);
}

// Retrieves the window's restore state override - if any - and returns it as a
// string.
std::string GetPlacementOverride(aura::Window* window) {
  gfx::Rect* bounds = window->GetProperty(kRestoreBoundsOverrideKey);
  if (bounds) {
    gfx::Rect restore_bounds = *bounds;
    ui::WindowShowState restore_state = ToWindowShowState(
        window->GetProperty(kRestoreWindowStateTypeOverrideKey));
    return GetPlacementString(restore_bounds, restore_state);
  }
  return std::string();
}

// Test that the restore state will be kept at its original value for
// session restoration purposes.
TEST_F(TabletModeWindowManagerTest, TestRestoreIntegrety) {
  gfx::Rect bounds(10, 10, 200, 50);
  std::unique_ptr<aura::Window> normal_window(CreateWindowWithWidget(bounds));
  std::unique_ptr<aura::Window> maximized_window(
      CreateWindowWithWidget(bounds));
  wm::GetWindowState(maximized_window.get())->Maximize();

  EXPECT_EQ(std::string(), GetPlacementOverride(normal_window.get()));
  EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));

  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);

  // With the maximization the override states should be returned in its
  // pre-maximized state.
  EXPECT_EQ(GetPlacementString(bounds, ui::SHOW_STATE_NORMAL),
            GetPlacementOverride(normal_window.get()));
  EXPECT_EQ(GetPlacementString(bounds, ui::SHOW_STATE_MAXIMIZED),
            GetPlacementOverride(maximized_window.get()));

  // Changing a window's state now does not change the returned result.
  wm::GetWindowState(maximized_window.get())->Minimize();
  EXPECT_EQ(GetPlacementString(bounds, ui::SHOW_STATE_MAXIMIZED),
            GetPlacementOverride(maximized_window.get()));

  // Destroy the manager again and check that the overrides get reset.
  DestroyTabletModeWindowManager();
  EXPECT_EQ(std::string(), GetPlacementOverride(normal_window.get()));
  EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));

  // Changing a window's state now does not bring the overrides back.
  wm::GetWindowState(maximized_window.get())->Restore();
  gfx::Rect new_bounds(10, 10, 200, 50);
  maximized_window->SetBounds(new_bounds);

  EXPECT_EQ(std::string(), GetPlacementOverride(maximized_window.get()));
}

// Test that windows which got created before the maximizer was created can be
// destroyed while the maximizer is still running.
TEST_F(TabletModeWindowManagerTest, PreCreateWindowsDeleteWhileActive) {
  TabletModeWindowManager* manager = NULL;
  {
    // Bounds for windows we know can be controlled.
    gfx::Rect rect1(10, 10, 200, 50);
    gfx::Rect rect2(10, 60, 200, 50);
    gfx::Rect rect3(20, 140, 100, 100);
    // Bounds for anything else.
    std::unique_ptr<aura::Window> w1(
        CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
    std::unique_ptr<aura::Window> w2(
        CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
    std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
        aura::client::WINDOW_TYPE_NORMAL, rect3));

    // Create the manager and make sure that all qualifying windows were
    // detected and changed.
    manager = CreateTabletModeWindowManager();
    ASSERT_TRUE(manager);
    EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  }
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
  DestroyTabletModeWindowManager();
}

// Test that windows which got created while the maximizer was running can get
// destroyed before the maximizer gets destroyed.
TEST_F(TabletModeWindowManagerTest, CreateWindowsAndDeleteWhileActive) {
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
  {
    // Bounds for windows we know can be controlled.
    gfx::Rect rect1(10, 10, 200, 50);
    gfx::Rect rect2(10, 60, 200, 50);
    gfx::Rect rect3(20, 140, 100, 100);
    std::unique_ptr<aura::Window> w1(
        CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
    std::unique_ptr<aura::Window> w2(
        CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));
    std::unique_ptr<aura::Window> w3(CreateFixedSizeNonMaximizableWindow(
        aura::client::WINDOW_TYPE_NORMAL, rect3));
    // Check that the windows got automatically maximized as well.
    EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
    EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMaximized());
    EXPECT_TRUE(wm::GetWindowState(w2.get())->IsMaximized());
    EXPECT_FALSE(wm::GetWindowState(w3.get())->IsMaximized());
  }
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
  DestroyTabletModeWindowManager();
}

// Test that windows which were maximized stay maximized.
TEST_F(TabletModeWindowManagerTest, MaximizedShouldRemainMaximized) {
  // Bounds for windows we know can be controlled.
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::GetWindowState(window.get())->Maximize();

  // Create the manager and make sure that the window gets detected.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
  EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized());

  // Destroy the manager again and check that the window will remain maximized.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized());
  wm::GetWindowState(window.get())->Restore();
  EXPECT_EQ(rect.ToString(), window->bounds().ToString());
}

// Test that minimized windows do neither get maximized nor restored upon
// entering tablet mode and get restored to their previous state after
// leaving.
TEST_F(TabletModeWindowManagerTest, MinimizedWindowBehavior) {
  // Bounds for windows we know can be controlled.
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> initially_minimized_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> initially_normal_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> initially_maximized_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::GetWindowState(initially_minimized_window.get())->Minimize();
  wm::GetWindowState(initially_maximized_window.get())->Maximize();

  // Create the manager and make sure that the window gets detected.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(3, manager->GetNumberOfManagedWindows());
  EXPECT_TRUE(
      wm::GetWindowState(initially_minimized_window.get())->IsMinimized());
  EXPECT_TRUE(wm::GetWindowState(initially_normal_window.get())->IsMaximized());
  EXPECT_TRUE(
      wm::GetWindowState(initially_maximized_window.get())->IsMaximized());
  // Now minimize the second window to check that upon leaving the window
  // will get restored to its minimized state.
  wm::GetWindowState(initially_normal_window.get())->Minimize();
  wm::GetWindowState(initially_maximized_window.get())->Minimize();
  EXPECT_TRUE(
      wm::GetWindowState(initially_minimized_window.get())->IsMinimized());
  EXPECT_TRUE(wm::GetWindowState(initially_normal_window.get())->IsMinimized());
  EXPECT_TRUE(
      wm::GetWindowState(initially_maximized_window.get())->IsMinimized());

  // Destroy the manager again and check that the window will get minimized.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(
      wm::GetWindowState(initially_minimized_window.get())->IsMinimized());
  EXPECT_FALSE(
      wm::GetWindowState(initially_normal_window.get())->IsMinimized());
  EXPECT_TRUE(
      wm::GetWindowState(initially_maximized_window.get())->IsMaximized());
}

// Check that resizing the desktop does reposition unmaximizable, unresizable &
// managed windows.
TEST_F(TabletModeWindowManagerTest, DesktopSizeChangeMovesUnmaximizable) {
  UpdateDisplay("400x400");
  // This window will move because it does not fit the new bounds.
  gfx::Rect rect(20, 300, 100, 100);
  std::unique_ptr<aura::Window> window1(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect));
  EXPECT_EQ(rect.ToString(), window1->bounds().ToString());

  // This window will not move because it does fit the new bounds.
  gfx::Rect rect2(20, 140, 100, 100);
  std::unique_ptr<aura::Window> window2(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect2));

  // Turning on the manager will reposition (but not resize) the window.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(2, manager->GetNumberOfManagedWindows());
  gfx::Rect moved_bounds(window1->bounds());
  EXPECT_NE(rect.origin().ToString(), moved_bounds.origin().ToString());
  EXPECT_EQ(rect.size().ToString(), moved_bounds.size().ToString());

  // Simulating a desktop resize should move the window again.
  UpdateDisplay("300x300");
  gfx::Rect new_moved_bounds(window1->bounds());
  EXPECT_NE(rect.origin().ToString(), new_moved_bounds.origin().ToString());
  EXPECT_EQ(rect.size().ToString(), new_moved_bounds.size().ToString());
  EXPECT_NE(moved_bounds.origin().ToString(), new_moved_bounds.ToString());

  // Turning off the mode should not restore to the initial coordinates since
  // the new resolution is smaller and the window was on the edge.
  DestroyTabletModeWindowManager();
  EXPECT_NE(rect.ToString(), window1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), window2->bounds().ToString());
}

// Check that windows return to original location if desktop size changes to
// something else and back while in tablet mode.
TEST_F(TabletModeWindowManagerTest, SizeChangeReturnWindowToOriginalPos) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> window(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect));

  // Turning on the manager will reposition (but not resize) the window.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
  gfx::Rect moved_bounds(window->bounds());
  EXPECT_NE(rect.origin().ToString(), moved_bounds.origin().ToString());
  EXPECT_EQ(rect.size().ToString(), moved_bounds.size().ToString());

  // Simulating a desktop resize should move the window again.
  ResizeDesktop(-10);
  gfx::Rect new_moved_bounds(window->bounds());
  EXPECT_NE(rect.origin().ToString(), new_moved_bounds.origin().ToString());
  EXPECT_EQ(rect.size().ToString(), new_moved_bounds.size().ToString());
  EXPECT_NE(moved_bounds.origin().ToString(), new_moved_bounds.ToString());

  // Then resize back to the original desktop size which should move windows
  // to their original location after leaving the tablet mode.
  ResizeDesktop(10);
  DestroyTabletModeWindowManager();
  EXPECT_EQ(rect.ToString(), window->bounds().ToString());
}

// Check that enabling of the tablet mode does not have an impact on the MRU
// order of windows.
TEST_F(TabletModeWindowManagerTest, ModeChangeKeepsMRUOrder) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> w2(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> w3(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> w4(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> w5(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));

  // The windows should be in the reverse order of creation in the MRU list.
  {
    aura::Window::Windows windows =
        Shell::Get()->mru_window_tracker()->BuildMruWindowList();

    EXPECT_EQ(w1.get(), windows[4]);
    EXPECT_EQ(w2.get(), windows[3]);
    EXPECT_EQ(w3.get(), windows[2]);
    EXPECT_EQ(w4.get(), windows[1]);
    EXPECT_EQ(w5.get(), windows[0]);
  }

  // Activating the window manager should keep the order.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(5, manager->GetNumberOfManagedWindows());
  {
    aura::Window::Windows windows =
        Shell::Get()->mru_window_tracker()->BuildMruWindowList();
    // We do not test maximization here again since that was done already.
    EXPECT_EQ(w1.get(), windows[4]);
    EXPECT_EQ(w2.get(), windows[3]);
    EXPECT_EQ(w3.get(), windows[2]);
    EXPECT_EQ(w4.get(), windows[1]);
    EXPECT_EQ(w5.get(), windows[0]);
  }

  // Destroying should still keep the order.
  DestroyTabletModeWindowManager();
  {
    aura::Window::Windows windows =
        Shell::Get()->mru_window_tracker()->BuildMruWindowList();
    // We do not test maximization here again since that was done already.
    EXPECT_EQ(w1.get(), windows[4]);
    EXPECT_EQ(w2.get(), windows[3]);
    EXPECT_EQ(w3.get(), windows[2]);
    EXPECT_EQ(w4.get(), windows[1]);
    EXPECT_EQ(w5.get(), windows[0]);
  }
}

// Check that a restore state change does always restore to maximized.
TEST_F(TabletModeWindowManagerTest, IgnoreRestoreStateChages) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  CreateTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsMaximized());
  window_state->Minimize();
  EXPECT_TRUE(window_state->IsMinimized());
  window_state->Restore();
  EXPECT_TRUE(window_state->IsMaximized());
  window_state->Restore();
  EXPECT_TRUE(window_state->IsMaximized());
  DestroyTabletModeWindowManager();
}

// Check that minimize and restore do the right thing.
TEST_F(TabletModeWindowManagerTest, TestMinimize) {
  gfx::Rect rect(10, 10, 100, 100);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  EXPECT_EQ(rect.ToString(), window->bounds().ToString());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_FALSE(window_state->IsMinimized());
  EXPECT_TRUE(window->IsVisible());

  window_state->Minimize();
  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_TRUE(window_state->IsMinimized());
  EXPECT_FALSE(window->IsVisible());

  window_state->Maximize();
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_FALSE(window_state->IsMinimized());
  EXPECT_TRUE(window->IsVisible());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_FALSE(window_state->IsMinimized());
  EXPECT_TRUE(window->IsVisible());
}

// Tests that minimized window can restore to pre-minimized show state after
// entering and leaving tablet mode (https://crbug.com/783310).
TEST_F(TabletModeWindowManagerTest, MinimizedEnterAndLeaveTabletMode) {
  gfx::Rect rect(10, 10, 100, 100);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->Minimize();
  EXPECT_TRUE(window_state->IsMinimized());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_TRUE(window_state->IsMinimized());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_TRUE(window_state->IsMinimized());

  window_state->Unminimize();
  EXPECT_FALSE(window_state->IsMinimized());
  window_state->Minimize();
  EXPECT_TRUE(window_state->IsMinimized());
}

// Tests that pre-minimized window show state is persistent after entering and
// leaving tablet mode, that is not cleared in tablet mode.
TEST_F(TabletModeWindowManagerTest, PersistPreMinimizedShowState) {
  gfx::Rect rect(10, 10, 100, 100);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->Maximize();
  window_state->Minimize();
  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
            window->GetProperty(aura::client::kPreMinimizedShowStateKey));

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  window_state->Unminimize();
  // Check that pre-minimized window show state is not cleared due to
  // unminimizing in tablet mode.
  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
            window->GetProperty(aura::client::kPreMinimizedShowStateKey));
  window_state->Minimize();
  EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED,
            window->GetProperty(aura::client::kPreMinimizedShowStateKey));

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  window_state->Unminimize();
  EXPECT_TRUE(window_state->IsMaximized());
}

// Tests unminimizing in tablet mode and then existing tablet mode should have
// pre-minimized window show state.
TEST_F(TabletModeWindowManagerTest, UnminimizeInTabletMode) {
  // Tests restoring to maximized show state.
  gfx::Rect rect(10, 10, 100, 100);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->Maximize();
  window_state->Minimize();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  window_state->Unminimize();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_TRUE(window_state->IsMaximized());

  // Tests restoring to normal show state.
  window_state->Restore();
  EXPECT_EQ(gfx::Rect(10, 10, 100, 100), window->GetBoundsInScreen());
  window_state->Minimize();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  window_state->Unminimize();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_EQ(gfx::Rect(10, 10, 100, 100), window->GetBoundsInScreen());
}

// Check that a full screen window remains full screen upon entering maximize
// mode. Furthermore, checks that this window is not full screen upon exiting
// tablet mode if it was un-full-screened while in tablet mode.
TEST_F(TabletModeWindowManagerTest, KeepFullScreenModeOn) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());

  Shelf* shelf = GetPrimaryShelf();

  // Allow the shelf to hide and set the pref.
  SetShelfAutoHideBehaviorPref(GetPrimaryDisplay().id(),
                               SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());

  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event);

  // With full screen, the shelf should get hidden.
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());

  CreateTabletModeWindowManager();

  // The Full screen mode should continue to be on.
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());

  // When exiting fullscreen, tablet mode should still be enabled, and the shelf
  // should be forced to visible for tablet mode.
  window_state->OnWMEvent(&event);
  EXPECT_FALSE(window_state->IsFullscreen());
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());

  // The shelf auto-hide preference should be restored when exiting tablet mode.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsFullscreen());
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
}

// Similar to the fullscreen mode, the pinned mode should be kept as well.
TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case1) {
  // Scenario: in the default state, pin a window, enter to the tablet mode,
  // then unpin.
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  EXPECT_FALSE(window_state->IsPinned());

  // Pin the window.
  {
    wm::WMEvent event(wm::WM_EVENT_PIN);
    window_state->OnWMEvent(&event);
  }
  EXPECT_TRUE(window_state->IsPinned());

  // Enter tablet mode. The pinned mode should continue to be on.
  CreateTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsPinned());

  // Then unpin.
  window_state->Restore();
  EXPECT_FALSE(window_state->IsPinned());

  // Exit tablet mode. The window should not be back to the pinned mode.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());
}

TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case2) {
  // Scenario: in the tablet mode, pin a window, exit tablet mode, then unpin.
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  EXPECT_FALSE(window_state->IsPinned());

  // Enter tablet mode.
  CreateTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());

  // Pin the window.
  {
    wm::WMEvent event(wm::WM_EVENT_PIN);
    window_state->OnWMEvent(&event);
  }
  EXPECT_TRUE(window_state->IsPinned());

  // Exit tablet mode. The pinned mode should continue to be on.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsPinned());

  // Then unpin.
  window_state->Restore();
  EXPECT_FALSE(window_state->IsPinned());

  // Enter tablet mode again for verification. The window should not be back to
  // the pinned mode.
  CreateTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());

  // Exit tablet mode.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());
}

TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case3) {
  // Scenario: in the default state, pin a window, enter to the tablet mode,
  // exit from the tablet mode, then unpin.
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  EXPECT_FALSE(window_state->IsPinned());

  // Pin the window.
  {
    wm::WMEvent event(wm::WM_EVENT_PIN);
    window_state->OnWMEvent(&event);
  }
  EXPECT_TRUE(window_state->IsPinned());

  // Enter tablet mode. The pinned mode should continue to be on.
  CreateTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsPinned());

  // Exit tablet mode. The pinned mode should continue to be on, too.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsPinned());

  // Then unpin.
  window_state->Restore();
  EXPECT_FALSE(window_state->IsPinned());

  // Enter tablet mode again for verification. The window should not be back to
  // the pinned mode.
  CreateTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());

  // Exit tablet mode.
  DestroyTabletModeWindowManager();
}

TEST_F(TabletModeWindowManagerTest, KeepPinnedModeOn_Case4) {
  // Scenario: in tablet mode, pin a window, exit tablet mode, enter tablet mode
  // again, then unpin.
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  EXPECT_FALSE(window_state->IsPinned());

  // Enter tablet mode.
  CreateTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());

  // Pin the window.
  {
    wm::WMEvent event(wm::WM_EVENT_PIN);
    window_state->OnWMEvent(&event);
  }
  EXPECT_TRUE(window_state->IsPinned());

  // Exit tablet mode. The pinned mode should continue to be on.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsPinned());

  // Enter tablet mode again. The pinned mode should continue to be on, too.
  CreateTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsPinned());

  // Then unpin.
  window_state->Restore();
  EXPECT_FALSE(window_state->IsPinned());

  // Exit tablet mode. The window should not be back to the pinned mode.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(window_state->IsPinned());
}

// Verifies that if a window is un-full-screened while in tablet mode,
// other changes to that window's state (such as minimizing it) are
// preserved upon exiting tablet mode.
TEST_F(TabletModeWindowManagerTest, MinimizePreservedAfterLeavingFullscreen) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());

  Shelf* shelf = GetPrimaryShelf();

  // Allow the shelf to hide and enter full screen.
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event);
  ASSERT_FALSE(window_state->IsMinimized());

  // Enter tablet mode, exit full screen, and then minimize the window.
  CreateTabletModeWindowManager();
  window_state->OnWMEvent(&event);
  window_state->Minimize();
  ASSERT_TRUE(window_state->IsMinimized());

  // The window should remain minimized when exiting tablet mode.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsMinimized());
}

// Tests that the auto-hide behavior is set to never auto-hide on tablet mode
// and gets reset based on pref after exiting tablet mode.
TEST_F(TabletModeWindowManagerTest, DisableAutoHideBehaviorOnTabletMode) {
  Shelf* shelf = GetPrimaryShelf();
  SetShelfAutoHideBehaviorPref(GetPrimaryDisplay().id(),
                               SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
  CreateTabletModeWindowManager();
  EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_NEVER, shelf->auto_hide_behavior());
  DestroyTabletModeWindowManager();
  EXPECT_EQ(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, shelf->auto_hide_behavior());
}

// Check that full screen mode can be turned on in tablet mode and remains
// upon coming back.
TEST_F(TabletModeWindowManagerTest, AllowFullScreenMode) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());

  Shelf* shelf = GetPrimaryShelf();

  // Allow the shelf to hide and set the pref.
  SetShelfAutoHideBehaviorPref(GetPrimaryDisplay().id(),
                               SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);

  EXPECT_FALSE(window_state->IsFullscreen());
  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());

  CreateTabletModeWindowManager();

  // Fullscreen should stay off, but the shelf is made visible in tablet mode.
  EXPECT_FALSE(window_state->IsFullscreen());
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());

  // After going into fullscreen mode, the shelf should be hidden.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event);
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());

  // With the destruction of the manager we should remain in full screen.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
}

// Check that the full screen mode will stay active when the tablet mode is
// ended.
TEST_F(TabletModeWindowManagerTest,
       FullScreenModeRemainsWhenCreatedInMaximizedMode) {
  CreateTabletModeWindowManager();

  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  wm::WMEvent event_full_screen(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event_full_screen);
  EXPECT_TRUE(window_state->IsFullscreen());

  // After the tablet mode manager is ended, full screen will remain.
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsFullscreen());
}

// Check that the full screen mode will stay active throughout a maximzied mode
// session.
TEST_F(TabletModeWindowManagerTest,
       FullScreenModeRemainsThroughTabletModeSwitch) {
  gfx::Rect rect(20, 140, 100, 100);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  wm::WMEvent event_full_screen(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event_full_screen);
  EXPECT_TRUE(window_state->IsFullscreen());

  CreateTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsFullscreen());
  DestroyTabletModeWindowManager();
  EXPECT_TRUE(window_state->IsFullscreen());
}

// Check that an empty window does not get restored to a tiny size.
TEST_F(TabletModeWindowManagerTest,
       CreateAndMaximizeInTabletModeShouldRetoreToGoodSizeGoingToDefault) {
  CreateTabletModeWindowManager();
  gfx::Rect rect;
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  w1->Show();
  wm::WindowState* window_state = wm::GetWindowState(w1.get());
  EXPECT_TRUE(window_state->IsMaximized());

  // There is a calling order in which the restore bounds can get set to an
  // empty rectangle. We simulate this here.
  window_state->SetRestoreBoundsInScreen(rect);
  EXPECT_TRUE(window_state->GetRestoreBoundsInScreen().IsEmpty());

  // Setting the window to a new size will physically not change the window,
  // but the restore size should get updated so that a restore later on will
  // return to this size.
  gfx::Rect requested_bounds(10, 20, 50, 70);
  w1->SetBounds(requested_bounds);
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_EQ(requested_bounds.ToString(),
            window_state->GetRestoreBoundsInScreen().ToString());

  DestroyTabletModeWindowManager();

  EXPECT_FALSE(window_state->IsMaximized());
  EXPECT_EQ(w1->bounds().ToString(), requested_bounds.ToString());
}

// Check that non maximizable windows cannot be dragged by the user.
TEST_F(TabletModeWindowManagerTest, TryToDesktopSizeDragUnmaximizable) {
  gfx::Rect rect(10, 10, 100, 100);
  std::unique_ptr<aura::Window> window(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect));
  EXPECT_EQ(rect.ToString(), window->bounds().ToString());

  // 1. Move the mouse over the caption and check that dragging the window does
  // change the location.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  generator.MoveMouseTo(gfx::Point(rect.x() + 2, rect.y() + 2));
  generator.PressLeftButton();
  generator.MoveMouseBy(10, 5);
  RunAllPendingInMessageLoop();
  generator.ReleaseLeftButton();
  gfx::Point first_dragged_origin = window->bounds().origin();
  EXPECT_EQ(rect.x() + 10, first_dragged_origin.x());
  EXPECT_EQ(rect.y() + 5, first_dragged_origin.y());

  // 2. Check that turning on the manager will stop allowing the window from
  // dragging.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  gfx::Rect center_bounds(window->bounds());
  EXPECT_NE(rect.origin().ToString(), center_bounds.origin().ToString());
  generator.MoveMouseTo(
      gfx::Point(center_bounds.x() + 1, center_bounds.y() + 1));
  generator.PressLeftButton();
  generator.MoveMouseBy(10, 5);
  RunAllPendingInMessageLoop();
  generator.ReleaseLeftButton();
  EXPECT_EQ(center_bounds.x(), window->bounds().x());
  EXPECT_EQ(center_bounds.y(), window->bounds().y());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);

  // 3. Releasing the mazimize manager again will restore the window to its
  // previous bounds and
  generator.MoveMouseTo(
      gfx::Point(first_dragged_origin.x() + 1, first_dragged_origin.y() + 1));
  generator.PressLeftButton();
  generator.MoveMouseBy(10, 5);
  RunAllPendingInMessageLoop();
  generator.ReleaseLeftButton();
  EXPECT_EQ(first_dragged_origin.x() + 10, window->bounds().x());
  EXPECT_EQ(first_dragged_origin.y() + 5, window->bounds().y());
}

// Test that overview is exited before entering / exiting tablet mode so that
// the window changes made by TabletModeWindowManager do not conflict with
// those made in WindowOverview.
TEST_F(TabletModeWindowManagerTest, ExitsOverview) {
  // Bounds for windows we know can be controlled.
  gfx::Rect rect1(10, 10, 200, 50);
  gfx::Rect rect2(10, 60, 200, 50);
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
  std::unique_ptr<aura::Window> w2(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect2));

  WindowSelectorController* window_selector_controller =
      Shell::Get()->window_selector_controller();
  ASSERT_TRUE(window_selector_controller->ToggleOverview());
  ASSERT_TRUE(window_selector_controller->IsSelecting());
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_FALSE(window_selector_controller->IsSelecting());

  ASSERT_TRUE(window_selector_controller->ToggleOverview());
  ASSERT_TRUE(window_selector_controller->IsSelecting());
  // Destroy the manager again and check that the windows return to their
  // previous state.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(window_selector_controller->IsSelecting());
}

// Test that an edge swipe from the top will end full screen mode.
TEST_F(TabletModeWindowManagerTest, ExitFullScreenWithEdgeSwipeFromTop) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> background_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> foreground_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* background_window_state =
      wm::GetWindowState(background_window.get());
  wm::WindowState* foreground_window_state =
      wm::GetWindowState(foreground_window.get());
  wm::ActivateWindow(foreground_window.get());
  CreateTabletModeWindowManager();

  // Fullscreen both windows.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  background_window_state->OnWMEvent(&event);
  foreground_window_state->OnWMEvent(&event);
  EXPECT_TRUE(background_window_state->IsFullscreen());
  EXPECT_TRUE(foreground_window_state->IsFullscreen());
  EXPECT_EQ(foreground_window.get(), wm::GetActiveWindow());

  // Do an edge swipe top into screen.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 100),
                                  base::TimeDelta::FromMilliseconds(20), 10);

  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  // Do a second edge swipe top into screen.
  generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 100),
                                  base::TimeDelta::FromMilliseconds(20), 10);

  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  DestroyTabletModeWindowManager();
}

// Test that an edge swipe from the bottom will end full screen mode.
TEST_F(TabletModeWindowManagerTest, ExitFullScreenWithEdgeSwipeFromBottom) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> background_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> foreground_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* background_window_state =
      wm::GetWindowState(background_window.get());
  wm::WindowState* foreground_window_state =
      wm::GetWindowState(foreground_window.get());
  wm::ActivateWindow(foreground_window.get());
  CreateTabletModeWindowManager();

  // Fullscreen both windows.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  background_window_state->OnWMEvent(&event);
  foreground_window_state->OnWMEvent(&event);
  EXPECT_TRUE(background_window_state->IsFullscreen());
  EXPECT_TRUE(foreground_window_state->IsFullscreen());
  EXPECT_EQ(foreground_window.get(), wm::GetActiveWindow());

  // Do an edge swipe bottom into screen.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  int y = Shell::GetPrimaryRootWindow()->bounds().bottom();
  generator.GestureScrollSequence(gfx::Point(50, y), gfx::Point(50, y - 100),
                                  base::TimeDelta::FromMilliseconds(20), 10);

  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  DestroyTabletModeWindowManager();
}

// Test that an edge touch press at the top will end full screen mode.
TEST_F(TabletModeWindowManagerTest, ExitFullScreenWithEdgeTouchAtTop) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> background_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> foreground_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* background_window_state =
      wm::GetWindowState(background_window.get());
  wm::WindowState* foreground_window_state =
      wm::GetWindowState(foreground_window.get());
  wm::ActivateWindow(foreground_window.get());
  CreateTabletModeWindowManager();

  // Fullscreen both windows.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  background_window_state->OnWMEvent(&event);
  foreground_window_state->OnWMEvent(&event);
  EXPECT_TRUE(background_window_state->IsFullscreen());
  EXPECT_TRUE(foreground_window_state->IsFullscreen());
  EXPECT_EQ(foreground_window.get(), wm::GetActiveWindow());

  // Touch tap on the top edge.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  generator.GestureTapAt(gfx::Point(100, 0));
  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  // Try the same again and see that nothing changes.
  generator.GestureTapAt(gfx::Point(100, 0));
  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  DestroyTabletModeWindowManager();
}

// Test that an edge touch press at the bottom will end full screen mode.
TEST_F(TabletModeWindowManagerTest, ExitFullScreenWithEdgeTouchAtBottom) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> background_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  std::unique_ptr<aura::Window> foreground_window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* background_window_state =
      wm::GetWindowState(background_window.get());
  wm::WindowState* foreground_window_state =
      wm::GetWindowState(foreground_window.get());
  wm::ActivateWindow(foreground_window.get());
  CreateTabletModeWindowManager();

  // Fullscreen both windows.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  background_window_state->OnWMEvent(&event);
  foreground_window_state->OnWMEvent(&event);
  EXPECT_TRUE(background_window_state->IsFullscreen());
  EXPECT_TRUE(foreground_window_state->IsFullscreen());
  EXPECT_EQ(foreground_window.get(), wm::GetActiveWindow());

  // Touch tap on the bottom edge.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  generator.GestureTapAt(
      gfx::Point(100, Shell::GetPrimaryRootWindow()->bounds().bottom() - 1));
  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  // Try the same again and see that nothing changes.
  generator.GestureTapAt(
      gfx::Point(100, Shell::GetPrimaryRootWindow()->bounds().bottom() - 1));
  EXPECT_FALSE(foreground_window_state->IsFullscreen());
  EXPECT_TRUE(background_window_state->IsFullscreen());

  DestroyTabletModeWindowManager();
}

// Test that an edge swipe from the top on an immersive mode window will not end
// full screen mode.
TEST_F(TabletModeWindowManagerTest, NoExitImmersiveModeWithEdgeSwipeFromTop) {
  std::unique_ptr<aura::Window> window(CreateWindow(
      aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(10, 10, 200, 50)));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  wm::ActivateWindow(window.get());
  CreateTabletModeWindowManager();

  // Fullscreen the window.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event);
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_FALSE(window_state->IsInImmersiveFullscreen());
  EXPECT_EQ(window.get(), wm::GetActiveWindow());

  window_state->SetInImmersiveFullscreen(true);

  // Do an edge swipe top into screen.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 100),
                                  base::TimeDelta::FromMilliseconds(20), 10);

  // It should have not exited full screen or immersive mode.
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_TRUE(window_state->IsInImmersiveFullscreen());

  DestroyTabletModeWindowManager();
}

// Test that an edge swipe from the bottom will not end immersive mode.
TEST_F(TabletModeWindowManagerTest,
       NoExitImmersiveModeWithEdgeSwipeFromBottom) {
  std::unique_ptr<aura::Window> window(CreateWindow(
      aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(10, 10, 200, 50)));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  wm::ActivateWindow(window.get());
  CreateTabletModeWindowManager();

  // Fullscreen the window.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
  window_state->OnWMEvent(&event);
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_FALSE(window_state->IsInImmersiveFullscreen());
  EXPECT_EQ(window.get(), wm::GetActiveWindow());
  window_state->SetInImmersiveFullscreen(true);
  EXPECT_TRUE(window_state->IsInImmersiveFullscreen());

  // Do an edge swipe bottom into screen.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  int y = Shell::GetPrimaryRootWindow()->bounds().bottom();
  generator.GestureScrollSequence(gfx::Point(50, y), gfx::Point(50, y - 100),
                                  base::TimeDelta::FromMilliseconds(20), 10);

  // The window should still be full screen and immersive.
  EXPECT_TRUE(window_state->IsFullscreen());
  EXPECT_TRUE(window_state->IsInImmersiveFullscreen());

  DestroyTabletModeWindowManager();
}

// Tests that windows with the always-on-top property are not managed by
// the TabletModeWindowManager while tablet mode is engaged (i.e.,
// they remain free-floating).
TEST_F(TabletModeWindowManagerTest, AlwaysOnTopWindows) {
  gfx::Rect rect1(10, 10, 200, 50);
  gfx::Rect rect2(20, 140, 100, 100);

  // Create two windows with the always-on-top property.
  std::unique_ptr<aura::Window> w1(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect1));
  std::unique_ptr<aura::Window> w2(CreateFixedSizeNonMaximizableWindow(
      aura::client::WINDOW_TYPE_NORMAL, rect2));
  w1->SetProperty(aura::client::kAlwaysOnTopKey, true);
  w2->SetProperty(aura::client::kAlwaysOnTopKey, true);
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());

  // Enter tablet mode. Neither window should be managed because they have
  // the always-on-top property set, which means that none of their properties
  // should change.
  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());

  // Remove the always-on-top property from both windows while in maximize
  // mode. The windows should become managed, which means they should be
  // maximized/centered and no longer be draggable.
  w1->SetProperty(aura::client::kAlwaysOnTopKey, false);
  w2->SetProperty(aura::client::kAlwaysOnTopKey, false);
  EXPECT_EQ(2, manager->GetNumberOfManagedWindows());
  EXPECT_TRUE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_NE(rect1.origin().ToString(), w1->bounds().origin().ToString());
  EXPECT_NE(rect1.size().ToString(), w1->bounds().size().ToString());
  EXPECT_NE(rect2.origin().ToString(), w2->bounds().origin().ToString());
  EXPECT_EQ(rect2.size().ToString(), w2->bounds().size().ToString());

  // Applying the always-on-top property to both windows while in maximize
  // mode should cause both windows to return to their original size,
  // position, and state.
  w1->SetProperty(aura::client::kAlwaysOnTopKey, true);
  w2->SetProperty(aura::client::kAlwaysOnTopKey, true);
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());

  // The always-on-top windows should not change when leaving tablet mode.
  DestroyTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(w1.get())->IsMaximized());
  EXPECT_FALSE(wm::GetWindowState(w2.get())->IsMaximized());
  EXPECT_EQ(rect1.ToString(), w1->bounds().ToString());
  EXPECT_EQ(rect2.ToString(), w2->bounds().ToString());
}

// Tests that windows that can control maximized bounds are not maximized
// and not tracked.
TEST_F(TabletModeWindowManagerTest, DontMaximizeClientManagedWindows) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));

  wm::GetWindowState(window.get())->set_allow_set_bounds_direct(true);

  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(window.get())->IsMaximized());
  EXPECT_EQ(0, manager->GetNumberOfManagedWindows());
}

// Verify that if tablet mode is started in the lock screen, windows will still
// be maximized after leaving the lock screen.
TEST_F(TabletModeWindowManagerTest, CreateManagerInLockScreen) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  ASSERT_FALSE(wm::GetWindowState(window.get())->IsMaximized());

  // Create the tablet mode window manager while inside the lock screen.
  GetSessionControllerClient()->RequestLockScreen();
  CreateTabletModeWindowManager();
  GetSessionControllerClient()->UnlockScreen();

  EXPECT_TRUE(wm::GetWindowState(window.get())->IsMaximized());

  DestroyTabletModeWindowManager();
  EXPECT_FALSE(wm::GetWindowState(window.get())->IsMaximized());
}

namespace {

class TestObserver : public wm::WindowStateObserver {
 public:
  TestObserver() = default;
  ~TestObserver() override = default;

  // wm::WindowStateObserver:
  void OnPreWindowStateTypeChange(wm::WindowState* window_state,
                                  mojom::WindowStateType old_type) override {
    pre_count_++;
    last_old_state_ = old_type;
  }

  void OnPostWindowStateTypeChange(wm::WindowState* window_state,
                                   mojom::WindowStateType old_type) override {
    post_count_++;
    post_layer_visibility_ = window_state->window()->layer()->visible();
    EXPECT_EQ(last_old_state_, old_type);
  }

  int GetPreCountAndReset() {
    int r = pre_count_;
    pre_count_ = 0;
    return r;
  }

  int GetPostCountAndReset() {
    int r = post_count_;
    post_count_ = 0;
    return r;
  }

  bool GetPostLayerVisibilityAndReset() {
    bool r = post_layer_visibility_;
    post_layer_visibility_ = false;
    return r;
  }

  mojom::WindowStateType GetLastOldStateAndReset() {
    mojom::WindowStateType r = last_old_state_;
    last_old_state_ = mojom::WindowStateType::DEFAULT;
    return r;
  }

 private:
  int pre_count_ = 0;
  int post_count_ = 0;
  bool post_layer_visibility_ = false;
  mojom::WindowStateType last_old_state_ = mojom::WindowStateType::DEFAULT;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

}  // namespace

TEST_F(TabletModeWindowManagerTest, StateTypeChange) {
  TestObserver observer;
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));

  CreateTabletModeWindowManager();

  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->AddObserver(&observer);

  window->Show();
  EXPECT_TRUE(window_state->IsMaximized());
  EXPECT_EQ(0, observer.GetPreCountAndReset());
  EXPECT_EQ(0, observer.GetPostCountAndReset());

  // Window is already in tablet mode.
  wm::WMEvent maximize_event(wm::WM_EVENT_MAXIMIZE);
  window_state->OnWMEvent(&maximize_event);
  EXPECT_EQ(0, observer.GetPreCountAndReset());
  EXPECT_EQ(0, observer.GetPostCountAndReset());

  wm::WMEvent fullscreen_event(wm::WM_EVENT_FULLSCREEN);
  window_state->OnWMEvent(&fullscreen_event);
  EXPECT_EQ(1, observer.GetPreCountAndReset());
  EXPECT_EQ(1, observer.GetPostCountAndReset());
  EXPECT_EQ(mojom::WindowStateType::MAXIMIZED,
            observer.GetLastOldStateAndReset());

  window_state->OnWMEvent(&maximize_event);
  EXPECT_EQ(1, observer.GetPreCountAndReset());
  EXPECT_EQ(1, observer.GetPostCountAndReset());
  EXPECT_EQ(mojom::WindowStateType::FULLSCREEN,
            observer.GetLastOldStateAndReset());

  wm::WMEvent minimize_event(wm::WM_EVENT_MINIMIZE);
  window_state->OnWMEvent(&minimize_event);
  EXPECT_EQ(1, observer.GetPreCountAndReset());
  EXPECT_EQ(1, observer.GetPostCountAndReset());
  EXPECT_EQ(mojom::WindowStateType::MAXIMIZED,
            observer.GetLastOldStateAndReset());

  wm::WMEvent restore_event(wm::WM_EVENT_NORMAL);
  window_state->OnWMEvent(&restore_event);
  EXPECT_EQ(1, observer.GetPreCountAndReset());
  EXPECT_EQ(1, observer.GetPostCountAndReset());
  EXPECT_EQ(mojom::WindowStateType::MINIMIZED,
            observer.GetLastOldStateAndReset());
  EXPECT_EQ(true, observer.GetPostLayerVisibilityAndReset());

  window_state->RemoveObserver(&observer);

  DestroyTabletModeWindowManager();
}

// Test that the restore state will be kept at its original value for
// session restoration purposes.
TEST_F(TabletModeWindowManagerTest, SetPropertyOnUnmanagedWindow) {
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  InitParams params(aura::client::WINDOW_TYPE_NORMAL);
  params.bounds = gfx::Rect(10, 10, 100, 100);
  params.show_on_creation = false;
  std::unique_ptr<aura::Window> window(CreateWindowInWatchedContainer(params));
  wm::GetWindowState(window.get())->set_allow_set_bounds_direct(true);
  window->SetProperty(aura::client::kAlwaysOnTopKey, true);
  window->Show();
}

// Test that the minimized window bounds doesn't change until it's unminimized.
TEST_F(TabletModeWindowManagerTest, DontChangeBoundsForMinimizedWindow) {
  gfx::Rect rect(10, 10, 200, 50);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->Minimize();
  EXPECT_TRUE(window_state->IsMinimized());

  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
  EXPECT_TRUE(window_state->IsMinimized());
  EXPECT_EQ(window->bounds(), rect);

  WindowSelectorController* window_selector_controller =
      Shell::Get()->window_selector_controller();
  window_selector_controller->ToggleOverview();
  EXPECT_EQ(window->bounds(), rect);

  // Exit overview mode will update all windows' bounds. However, if the window
  // is minimized, the bounds will not be updated.
  window_selector_controller->ToggleOverview();
  EXPECT_EQ(window->bounds(), rect);
}

// Test that if a window is currently in tab-dragging process, its window bounds
// should not updated.
TEST_F(TabletModeWindowManagerTest, DontChangeBoundsForTabDraggingWindow) {
  gfx::Rect rect(0, 0, 200, 200);
  std::unique_ptr<aura::Window> window(
      CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
  // Now put the window in tab-dragging process.
  window->SetProperty(ash::kIsDraggingTabsKey, true);

  TabletModeWindowManager* manager = CreateTabletModeWindowManager();
  ASSERT_TRUE(manager);
  EXPECT_EQ(1, manager->GetNumberOfManagedWindows());
  EXPECT_EQ(window->bounds(), rect);
}

}  // namespace ash
