// Copyright 2013 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/workspace_controller.h"

#include <map>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/screen_util.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/status_area_widget.h"
#include "ash/test/ash_test_base.h"
#include "ash/window_factory.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "ash/wm/workspace/workspace_window_resizer.h"
#include "base/strings/string_number_conversions.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/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h"

using aura::Window;

namespace ash {

// Returns a string containing the names of all the children of |window| (in
// order). Each entry is separated by a space.
std::string GetWindowNames(const aura::Window* window) {
  std::string result;
  for (size_t i = 0; i < window->children().size(); ++i) {
    if (i != 0)
      result += " ";
    result += window->children()[i]->GetName();
  }
  return result;
}

// Returns a string containing the names of windows corresponding to each of the
// child layers of |window|'s layer. Any layers that don't correspond to a child
// Window of |window| are ignored. The result is ordered based on the layer
// ordering.
std::string GetLayerNames(const aura::Window* window) {
  typedef std::map<const ui::Layer*, std::string> LayerToWindowNameMap;
  LayerToWindowNameMap window_names;
  for (size_t i = 0; i < window->children().size(); ++i) {
    window_names[window->children()[i]->layer()] =
        window->children()[i]->GetName();
  }

  std::string result;
  const std::vector<ui::Layer*>& layers(window->layer()->children());
  for (size_t i = 0; i < layers.size(); ++i) {
    LayerToWindowNameMap::iterator layer_i = window_names.find(layers[i]);
    if (layer_i != window_names.end()) {
      if (!result.empty())
        result += " ";
      result += layer_i->second;
    }
  }
  return result;
}

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

  aura::Window* CreateTestWindowUnparented() {
    aura::Window* window = window_factory::NewWindow().release();
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    window->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window->Init(ui::LAYER_TEXTURED);
    return window;
  }

  aura::Window* CreateTestWindow() {
    aura::Window* window = window_factory::NewWindow().release();
    window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
    window->SetType(aura::client::WINDOW_TYPE_NORMAL);
    window->Init(ui::LAYER_TEXTURED);
    ParentWindowInPrimaryRootWindow(window);
    return window;
  }

  aura::Window* CreateBrowserLikeWindow(const gfx::Rect& bounds) {
    aura::Window* window = CreateTestWindow();
    window->SetBounds(bounds);
    wm::WindowState* window_state = wm::GetWindowState(window);
    window_state->SetWindowPositionManaged(true);
    window->Show();
    return window;
  }

  aura::Window* CreatePopupLikeWindow(const gfx::Rect& bounds) {
    aura::Window* window = CreateTestWindowInShellWithBounds(bounds);
    window->Show();
    return window;
  }

  aura::Window* GetDesktop() {
    return Shell::GetContainer(Shell::GetPrimaryRootWindow(),
                               desks_util::GetActiveDeskContainerId());
  }

  gfx::Rect GetFullscreenBounds(aura::Window* window) {
    return display::Screen::GetScreen()
        ->GetDisplayNearestWindow(window)
        .bounds();
  }

  ShelfWidget* shelf_widget() { return GetPrimaryShelf()->shelf_widget(); }

  ShelfLayoutManager* shelf_layout_manager() {
    return GetPrimaryShelf()->shelf_layout_manager();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WorkspaceControllerTest);
};

// Assertions around adding a normal window.
TEST_F(WorkspaceControllerTest, AddNormalWindowWhenEmpty) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));

  wm::WindowState* window_state = wm::GetWindowState(w1.get());

  EXPECT_FALSE(window_state->HasRestoreBounds());

  w1->Show();

  EXPECT_FALSE(window_state->HasRestoreBounds());

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());

  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());

  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
}

// Assertions around maximizing/unmaximizing.
TEST_F(WorkspaceControllerTest, SingleMaximizeWindow) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));

  w1->Show();
  wm::ActivateWindow(w1.get());

  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());

  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());

  // Maximize the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);

  EXPECT_TRUE(wm::IsActiveWindow(w1.get()));

  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(screen_util::GetMaximizedWindowBoundsInParent(w1.get()).width(),
            w1->bounds().width());
  EXPECT_EQ(screen_util::GetMaximizedWindowBoundsInParent(w1.get()).height(),
            w1->bounds().height());

  // Restore the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);

  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());
}

// Assertions around two windows and toggling one to be fullscreen.
TEST_F(WorkspaceControllerTest, FullscreenWithNormalWindow) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  std::unique_ptr<Window> w2(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  w1->Show();

  ASSERT_TRUE(w1->layer() != NULL);
  EXPECT_TRUE(w1->layer()->visible());

  w2->SetBounds(gfx::Rect(0, 0, 50, 51));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Both windows should be in the same workspace.
  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(w2.get(), GetDesktop()->children()[1]);

  gfx::Rect work_area(screen_util::GetMaximizedWindowBoundsInParent(w1.get()));
  EXPECT_EQ(work_area.width(), w2->bounds().width());
  EXPECT_EQ(work_area.height(), w2->bounds().height());

  // Restore w2, which should then go back to one workspace.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(50, w2->bounds().width());
  EXPECT_EQ(51, w2->bounds().height());
  EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
}

// Makes sure requests to change the bounds of a normal window go through.
TEST_F(WorkspaceControllerTest, ChangeBoundsOfNormalWindow) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->Show();

  // Setting the bounds should go through since the window is in the normal
  // workspace.
  w1->SetBounds(gfx::Rect(0, 0, 200, 500));
  EXPECT_EQ(200, w1->bounds().width());
  EXPECT_EQ(500, w1->bounds().height());
}

// Verifies the bounds is not altered when showing and grid is enabled.
TEST_F(WorkspaceControllerTest, SnapToGrid) {
  std::unique_ptr<Window> w1(CreateTestWindowUnparented());
  w1->SetBounds(gfx::Rect(1, 6, 25, 30));
  ParentWindowInPrimaryRootWindow(w1.get());
  // We are not aligning this anymore this way. When the window gets shown
  // the window is expected to be handled differently, but this cannot be
  // tested with this test. So the result of this test should be that the
  // bounds are exactly as passed in.
  EXPECT_EQ("1,6 25x30", w1->bounds().ToString());
}

// Assertions around a fullscreen window.
TEST_F(WorkspaceControllerTest, SingleFullscreenWindow) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 250, 251));
  // Make the window fullscreen.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  w1->Show();
  wm::ActivateWindow(w1.get());

  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(GetFullscreenBounds(w1.get()).width(), w1->bounds().width());
  EXPECT_EQ(GetFullscreenBounds(w1.get()).height(), w1->bounds().height());

  // Restore the window. Use SHOW_STATE_DEFAULT as that is what we'll end up
  // with when using views::Widget.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_DEFAULT);
  EXPECT_EQ("0,0 250x251", w1->bounds().ToString());

  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(250, w1->bounds().width());
  EXPECT_EQ(251, w1->bounds().height());

  // Back to fullscreen.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_EQ(w1.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(GetFullscreenBounds(w1.get()).width(), w1->bounds().width());
  EXPECT_EQ(GetFullscreenBounds(w1.get()).height(), w1->bounds().height());
  wm::WindowState* window_state = wm::GetWindowState(w1.get());

  ASSERT_TRUE(window_state->HasRestoreBounds());
  EXPECT_EQ("0,0 250x251", window_state->GetRestoreBoundsInScreen().ToString());
}

// Assertions around minimizing a single window.
TEST_F(WorkspaceControllerTest, MinimizeSingleWindow) {
  std::unique_ptr<Window> w1(CreateTestWindow());

  w1->Show();

  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_FALSE(w1->layer()->IsDrawn());
  EXPECT_TRUE(w1->layer()->GetTargetTransform().IsIdentity());

  // Show the window.
  w1->Show();
  EXPECT_TRUE(wm::GetWindowState(w1.get())->IsNormalStateType());
  EXPECT_TRUE(w1->layer()->IsDrawn());
}

// Assertions around minimizing a fullscreen window.
TEST_F(WorkspaceControllerTest, MinimizeFullscreenWindow) {
  // Two windows, w1 normal, w2 fullscreen.
  std::unique_ptr<Window> w1(CreateTestWindow());
  std::unique_ptr<Window> w2(CreateTestWindow());
  w1->Show();
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  w2->Show();

  wm::WindowState* w1_state = wm::GetWindowState(w1.get());
  wm::WindowState* w2_state = wm::GetWindowState(w2.get());

  w2_state->Activate();

  // Minimize w2.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_TRUE(w1->layer()->IsDrawn());
  EXPECT_FALSE(w2->layer()->IsDrawn());

  // Show the window, which should trigger unminimizing.
  w2->Show();
  w2_state->Activate();

  EXPECT_TRUE(w2_state->IsFullscreen());
  EXPECT_TRUE(w1->layer()->IsDrawn());
  EXPECT_TRUE(w2->layer()->IsDrawn());

  // Minimize the window, which should hide the window.
  EXPECT_TRUE(w2_state->IsActive());
  w2_state->Minimize();
  EXPECT_FALSE(w2_state->IsActive());
  EXPECT_FALSE(w2->layer()->IsDrawn());
  EXPECT_TRUE(w1_state->IsActive());
  EXPECT_EQ(w2.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(w1.get(), GetDesktop()->children()[1]);

  // Make the window normal.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  // Setting back to normal doesn't change the activation.
  EXPECT_FALSE(w2_state->IsActive());
  EXPECT_TRUE(w1_state->IsActive());
  EXPECT_EQ(w2.get(), GetDesktop()->children()[0]);
  EXPECT_EQ(w1.get(), GetDesktop()->children()[1]);
  EXPECT_TRUE(w2->layer()->IsDrawn());
}

// Verifies ShelfLayoutManager's visibility/auto-hide state is correctly
// updated.
TEST_F(WorkspaceControllerTest, ShelfStateUpdated) {
  // Since ShelfLayoutManager queries for mouse location, move the mouse so
  // it isn't over the shelf.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
                                     gfx::Point());
  generator.MoveMouseTo(0, 0);

  std::unique_ptr<Window> w1(CreateTestWindow());
  const gfx::Rect w1_bounds(0, 1, 101, 102);
  Shelf* shelf = GetPrimaryShelf();
  shelf->SetAutoHideBehavior(ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  const gfx::Rect touches_shelf_bounds(
      0, shelf_layout_manager()->GetIdealBounds().y() - 10, 101, 102);
  // Move |w1| to overlap the shelf.
  w1->SetBounds(touches_shelf_bounds);
  w1->Show();

  wm::ActivateWindow(w1.get());
  w1->SetBounds(w1_bounds);
  w1->Show();
  wm::ActivateWindow(w1.get());

  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());

  // Maximize the window.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());

  // Restore.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());

  // Fullscreen.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());

  // Normal.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  w1->SetBounds(w1_bounds);

  // Maximize again.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());

  // Minimize.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());

  // Since the restore from minimize will restore to the pre-minimize
  // state (tested elsewhere), we abandon the current size and restore
  // rect and set them to the window.
  wm::WindowState* window_state = wm::GetWindowState(w1.get());

  gfx::Rect restore = window_state->GetRestoreBoundsInScreen();
  EXPECT_EQ(gfx::Rect(0, 0, 800, 600).ToString(), w1->bounds().ToString());
  EXPECT_EQ("0,1 101x102", restore.ToString());
  window_state->ClearRestoreBounds();
  w1->SetBounds(restore);

  // Restore.
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());

  // Create another window, maximized.
  std::unique_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  EXPECT_EQ(
      screen_util::GetMaximizedWindowBoundsInParent(w2->parent()).ToString(),
      w2->bounds().ToString());

  // Switch to w1.
  wm::ActivateWindow(w1.get());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  EXPECT_EQ(
      screen_util::GetMaximizedWindowBoundsInParent(w2->parent()).ToString(),
      w2->bounds().ToString());

  // Switch to w2.
  wm::ActivateWindow(w2.get());
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
  EXPECT_EQ("0,1 101x102", w1->bounds().ToString());
  EXPECT_EQ(screen_util::GetMaximizedWindowBoundsInParent(w2.get()).ToString(),
            w2->bounds().ToString());
}

// Verifies going from maximized to minimized sets the right state for painting
// the background of the launcher.
TEST_F(WorkspaceControllerTest, MinimizeResetsVisibility) {
  // TODO(bruthig|xiyuan): Move SessionState setup into AshTestBase or
  // AshTestHelper.
  SessionInfo info;
  info.state = session_manager::SessionState::ACTIVE;
  ash::Shell::Get()->session_controller()->SetSessionInfo(info);

  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  wm::ActivateWindow(w1.get());
  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_EQ(SHELF_BACKGROUND_MAXIMIZED, shelf_widget()->GetBackgroundType());

  w1->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_EQ(SHELF_VISIBLE, GetPrimaryShelf()->GetVisibilityState());
  EXPECT_EQ(SHELF_BACKGROUND_DEFAULT, shelf_widget()->GetBackgroundType());
}

// Verifies window visibility during various workspace changes.
TEST_F(WorkspaceControllerTest, VisibilityTests) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->Show();
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());

  // Create another window, activate it and make it fullscreen.
  std::unique_ptr<Window> w2(CreateTestWindow());
  w2->Show();
  wm::ActivateWindow(w2.get());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());

  // Switch to w1. |w1| should be visible on top of |w2|.
  wm::ActivateWindow(w1.get());
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w2->IsVisible());

  // Switch back to |w2|.
  wm::ActivateWindow(w2.get());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());

  // Restore |w2|, both windows should be visible.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_TRUE(w1->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());

  // Make |w2| fullscreen again, then close it.
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  w2->Hide();
  EXPECT_FALSE(w2->IsVisible());
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());

  // Create |w2| and maximize it.
  w2.reset(CreateTestWindow());
  w2->Show();
  wm::ActivateWindow(w2.get());
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_TRUE(w2->IsVisible());
  EXPECT_EQ(1.0f, w2->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());

  // Close |w2|.
  w2.reset();
  EXPECT_EQ(1.0f, w1->layer()->GetCombinedOpacity());
  EXPECT_TRUE(w1->IsVisible());
}

// Verifies windows that are offscreen don't move when switching workspaces.
TEST_F(WorkspaceControllerTest, DontMoveOnSwitch) {
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
                                     gfx::Point());
  generator.MoveMouseTo(0, 0);

  std::unique_ptr<Window> w1(CreateTestWindow());
  const gfx::Rect touches_shelf_bounds(
      0, shelf_layout_manager()->GetIdealBounds().y() - 10, 101, 102);
  // Move |w1| to overlap the shelf.
  w1->SetBounds(touches_shelf_bounds);
  w1->Show();
  wm::ActivateWindow(w1.get());

  // Create another window and maximize it.
  std::unique_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Switch to w1.
  wm::ActivateWindow(w1.get());
  EXPECT_EQ(touches_shelf_bounds.ToString(), w1->bounds().ToString());
}

// Verifies that windows that are completely offscreen move when switching
// workspaces.
TEST_F(WorkspaceControllerTest, MoveOnSwitch) {
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
                                     gfx::Point());
  generator.MoveMouseTo(0, 0);

  std::unique_ptr<Window> w1(CreateTestWindow());
  const gfx::Rect w1_bounds(0, shelf_layout_manager()->GetIdealBounds().y(),
                            100, 200);
  // Move |w1| so that the top edge is the same as the top edge of the shelf.
  w1->SetBounds(w1_bounds);
  w1->Show();
  wm::ActivateWindow(w1.get());
  EXPECT_EQ(w1_bounds.ToString(), w1->bounds().ToString());

  // Create another window and maximize it.
  std::unique_ptr<Window> w2(CreateTestWindow());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  w2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  w2->Show();
  wm::ActivateWindow(w2.get());

  // Increase the size of the WorkAreaInsets. This would make |w1| fall
  // completely out of the display work area.
  gfx::Insets insets =
      display::Screen::GetScreen()->GetPrimaryDisplay().GetWorkAreaInsets();
  insets.Set(0, 0, insets.bottom() + 30, 0);
  Shell::Get()->SetDisplayWorkAreaInsets(w1.get(), insets);

  // Switch to w1. The window should have moved.
  wm::ActivateWindow(w1.get());
  EXPECT_NE(w1_bounds.ToString(), w1->bounds().ToString());
}

namespace {

// WindowDelegate used by DontCrashOnChangeAndActivate.
class DontCrashOnChangeAndActivateDelegate
    : public aura::test::TestWindowDelegate {
 public:
  DontCrashOnChangeAndActivateDelegate() : window_(NULL) {}

  void set_window(aura::Window* window) { window_ = window; }

  // WindowDelegate overrides:
  void OnBoundsChanged(const gfx::Rect& old_bounds,
                       const gfx::Rect& new_bounds) override {
    if (window_) {
      wm::ActivateWindow(window_);
      window_ = NULL;
    }
  }

 private:
  aura::Window* window_;

  DISALLOW_COPY_AND_ASSIGN(DontCrashOnChangeAndActivateDelegate);
};

}  // namespace

// Exercises possible crash in W2. Here's the sequence:
// . minimize a maximized window.
// . remove the window (which happens when switching displays).
// . add the window back.
// . show the window and during the bounds change activate it.
TEST_F(WorkspaceControllerTest, DontCrashOnChangeAndActivate) {
  // Force the shelf
  Shelf* shelf = GetPrimaryShelf();
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);

  DontCrashOnChangeAndActivateDelegate delegate;
  std::unique_ptr<Window> w1(CreateTestWindowInShellWithDelegate(
      &delegate, 1000, gfx::Rect(10, 11, 250, 251)));

  w1->Show();
  wm::WindowState* w1_state = wm::GetWindowState(w1.get());
  w1_state->Activate();
  w1_state->Maximize();
  w1_state->Minimize();

  w1->parent()->RemoveChild(w1.get());

  // Do this so that when we Show() the window a resize occurs and we make the
  // window active.
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);

  ParentWindowInPrimaryRootWindow(w1.get());
  delegate.set_window(w1.get());
  w1->Show();
}

// Verifies a window with a transient parent not managed by workspace works.
TEST_F(WorkspaceControllerTest, TransientParent) {
  std::unique_ptr<Window> w1(CreateTestWindow());
  w1->SetBounds(gfx::Rect(0, 0, 100, 100));
  w1->Show();

  // Normal window with no transient parent.
  std::unique_ptr<Window> w3(CreateTestWindow());
  w3->SetBounds(gfx::Rect(10, 11, 250, 251));
  w3->Show();
  wm::ActivateWindow(w3.get());

  // Window with a transient parent.
  std::unique_ptr<Window> w2(CreateTestWindowUnparented());
  ::wm::AddTransientChild(w1.get(), w2.get());
  w2->SetBounds(gfx::Rect(10, 11, 250, 251));
  ParentWindowInPrimaryRootWindow(w2.get());
  w2->Show();
  wm::ActivateWindow(w2.get());

  // The window with the transient parent should get added to the same parent as
  // the normal window.
  EXPECT_EQ(w3->parent(), w2->parent());
}

// Test the placement of newly created windows.
TEST_F(WorkspaceControllerTest, BasicAutoPlacingOnCreate) {
  UpdateDisplay("1600x1200");
  // Creating a popup handler here to make sure it does not interfere with the
  // existing windows.
  gfx::Rect source_browser_bounds(16, 32, 640, 320);
  std::unique_ptr<aura::Window> browser_window(
      CreateBrowserLikeWindow(source_browser_bounds));

  // Creating a popup to make sure it does not interfere with the positioning.
  std::unique_ptr<aura::Window> browser_popup(
      CreatePopupLikeWindow(gfx::Rect(16, 32, 128, 256)));

  browser_window->Show();
  browser_popup->Show();

  {  // With a shown window it's size should get returned.
    std::unique_ptr<aura::Window> new_browser_window(
        CreateBrowserLikeWindow(source_browser_bounds));
    // The position should be right flush.
    EXPECT_EQ("960,32 640x320", new_browser_window->bounds().ToString());
  }

  {  // With the window shown - but more on the right side then on the left
    // side (and partially out of the screen), it should default to the other
    // side and inside the screen.
    gfx::Rect source_browser_bounds(gfx::Rect(1000, 600, 640, 320));
    browser_window->SetBounds(source_browser_bounds);

    std::unique_ptr<aura::Window> new_browser_window(
        CreateBrowserLikeWindow(source_browser_bounds));
    // The position should be left & bottom flush.
    EXPECT_EQ("0,600 640x320", new_browser_window->bounds().ToString());

    // If the other window was already beyond the point to get right flush
    // it will remain where it is.
    EXPECT_EQ("1000,600 640x320", browser_window->bounds().ToString());
  }

  {  // Make sure that popups do not get changed.
    std::unique_ptr<aura::Window> new_popup_window(
        CreatePopupLikeWindow(gfx::Rect(50, 100, 300, 150)));
    EXPECT_EQ("50,100 300x150", new_popup_window->bounds().ToString());
  }

  browser_window->Hide();
  {  // If a window is there but not shown the default should be centered.
    std::unique_ptr<aura::Window> new_browser_window(
        CreateBrowserLikeWindow(gfx::Rect(50, 100, 300, 150)));
    EXPECT_EQ("650,100 300x150", new_browser_window->bounds().ToString());
  }
}

// Test that adding a second window shifts both the first window and its
// transient child.
TEST_F(WorkspaceControllerTest, AutoPlacingMovesTransientChild) {
  // Create an auto-positioned window.
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  gfx::Rect desktop_area = window1->parent()->bounds();
  wm::GetWindowState(window1.get())->SetWindowPositionManaged(true);
  // Hide and then show |window1| to trigger auto-positioning logic.
  window1->Hide();
  window1->SetBounds(gfx::Rect(16, 32, 300, 300));
  window1->Show();

  // |window1| should be horizontally centered.
  int x_window1 = (desktop_area.width() - 300) / 2;
  EXPECT_EQ(base::NumberToString(x_window1) + ",32 300x300",
            window1->bounds().ToString());

  // Create a |child| window and make it a transient child of |window1|.
  std::unique_ptr<Window> child(CreateTestWindowUnparented());
  ::wm::AddTransientChild(window1.get(), child.get());
  const int x_child = x_window1 + 50;
  child->SetBounds(gfx::Rect(x_child, 20, 200, 200));
  ParentWindowInPrimaryRootWindow(child.get());
  child->Show();
  wm::ActivateWindow(child.get());

  // The |child| should be where it was created.
  EXPECT_EQ(base::NumberToString(x_child) + ",20 200x200",
            child->bounds().ToString());

  // Create and show a second window forcing the first window and its child to
  // move.
  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  wm::GetWindowState(window2.get())->SetWindowPositionManaged(true);
  // Hide and then show |window2| to trigger auto-positioning logic.
  window2->Hide();
  window2->SetBounds(gfx::Rect(32, 48, 250, 250));
  window2->Show();

  // Check that both |window1| and |child| have moved left.
  EXPECT_EQ("0,32 300x300", window1->bounds().ToString());
  int x = x_child - x_window1;
  EXPECT_EQ(base::NumberToString(x) + ",20 200x200",
            child->bounds().ToString());
  // Check that |window2| has moved right.
  x = desktop_area.width() - window2->bounds().width();
  EXPECT_EQ(base::NumberToString(x) + ",48 250x250",
            window2->bounds().ToString());
}

// Test the basic auto placement of one and or two windows in a "simulated
// session" of sequential window operations.
TEST_F(WorkspaceControllerTest, BasicAutoPlacingOnShowHide) {
  // Test 1: In case there is no manageable window, no window should shift.

  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();

  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  // Trigger the auto window placement function by making it visible.
  // Note that the bounds are getting changed while it is invisible.
  window2->Hide();
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));
  window2->Show();

  // Check the initial position of the windows is unchanged.
  EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
  EXPECT_EQ("32,48 256x512", window2->bounds().ToString());

  // Remove the second window and make sure that the first window
  // does NOT get centered.
  window2.reset();
  EXPECT_EQ("16,32 640x320", window1->bounds().ToString());

  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  // Test 2: Set up two managed windows and check their auto positioning.
  window1_state->SetWindowPositionManaged(true);

  std::unique_ptr<aura::Window> window3(CreateTestWindowInShellWithId(2));
  wm::GetWindowState(window3.get())->SetWindowPositionManaged(true);
  // To avoid any auto window manager changes due to SetBounds, the window
  // gets first hidden and then shown again.
  window3->Hide();
  window3->SetBounds(gfx::Rect(32, 48, 256, 512));
  window3->Show();
  // |window1| should be flush left and |window3| flush right.
  EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window3->bounds().width()) +
          ",48 256x512",
      window3->bounds().ToString());

  // After removing |window3|, |window1| should be centered again.
  window3.reset();
  EXPECT_EQ(base::NumberToString(
                (desktop_area.width() - window1->bounds().width()) / 2) +
                ",32 640x320",
            window1->bounds().ToString());

  // Test 3: Set up a manageable and a non manageable window and check
  // positioning.
  std::unique_ptr<aura::Window> window4(CreateTestWindowInShellWithId(3));
  // To avoid any auto window manager changes due to SetBounds, the window
  // gets first hidden and then shown again.
  window1->Hide();
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  window4->SetBounds(gfx::Rect(32, 48, 256, 512));
  window1->Show();
  // |window1| should be centered and |window4| untouched.
  EXPECT_EQ(base::NumberToString(
                (desktop_area.width() - window1->bounds().width()) / 2) +
                ",32 640x320",
            window1->bounds().ToString());
  EXPECT_EQ("32,48 256x512", window4->bounds().ToString());

  // Test4: A single manageable window should get centered.
  window4.reset();
  window1_state->set_bounds_changed_by_user(false);
  // Trigger the auto window placement function by showing (and hiding) it.
  window1->Hide();
  window1->Show();
  // |window1| should be centered.
  EXPECT_EQ(base::NumberToString(
                (desktop_area.width() - window1->bounds().width()) / 2) +
                ",32 640x320",
            window1->bounds().ToString());
}

// Test the proper usage of user window movement interaction.
TEST_F(WorkspaceControllerTest, TestUserMovedWindowRepositioning) {
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();
  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));
  window1->Hide();
  window2->Hide();
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  wm::WindowState* window2_state = wm::GetWindowState(window2.get());

  window1_state->SetWindowPositionManaged(true);
  window2_state->SetWindowPositionManaged(true);
  EXPECT_FALSE(window1_state->bounds_changed_by_user());
  EXPECT_FALSE(window2_state->bounds_changed_by_user());

  // Check that the current location gets preserved if the user has
  // positioned it previously.
  window1_state->set_bounds_changed_by_user(true);
  window1->Show();
  EXPECT_EQ("16,32 640x320", window1->bounds().ToString());
  // Flag should be still set.
  EXPECT_TRUE(window1_state->bounds_changed_by_user());
  EXPECT_FALSE(window2_state->bounds_changed_by_user());

  // Turn on the second window and make sure that both windows are now
  // positionable again (user movement cleared).
  window2->Show();

  // |window1| should be flush left and |window2| flush right.
  EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window2->bounds().width()) +
          ",48 256x512",
      window2->bounds().ToString());
  // FLag should now be reset.
  EXPECT_FALSE(window1_state->bounds_changed_by_user());
  EXPECT_FALSE(window2_state->bounds_changed_by_user());

  // Going back to one shown window should keep the state.
  window1_state->set_bounds_changed_by_user(true);
  window2->Hide();
  EXPECT_EQ("0,32 640x320", window1->bounds().ToString());
  EXPECT_TRUE(window1_state->bounds_changed_by_user());
}

// Test if the single window will be restored at original position.
TEST_F(WorkspaceControllerTest, TestSingleWindowsRestoredBounds) {
  std::unique_ptr<aura::Window> window1(
      CreateTestWindowInShellWithBounds(gfx::Rect(100, 100, 100, 100)));
  std::unique_ptr<aura::Window> window2(
      CreateTestWindowInShellWithBounds(gfx::Rect(110, 110, 100, 100)));
  std::unique_ptr<aura::Window> window3(
      CreateTestWindowInShellWithBounds(gfx::Rect(120, 120, 100, 100)));
  window1->Hide();
  window2->Hide();
  window3->Hide();
  wm::GetWindowState(window1.get())->SetWindowPositionManaged(true);
  wm::GetWindowState(window2.get())->SetWindowPositionManaged(true);
  wm::GetWindowState(window3.get())->SetWindowPositionManaged(true);

  window1->Show();
  wm::ActivateWindow(window1.get());
  window2->Show();
  wm::ActivateWindow(window2.get());
  window3->Show();
  wm::ActivateWindow(window3.get());
  EXPECT_EQ(0, window1->bounds().x());
  EXPECT_EQ(window2->GetRootWindow()->bounds().right(),
            window2->bounds().right());
  EXPECT_EQ(0, window3->bounds().x());

  window1->Hide();
  EXPECT_EQ(window2->GetRootWindow()->bounds().right(),
            window2->bounds().right());
  EXPECT_EQ(0, window3->bounds().x());

  // Being a single window will retore the original location.
  window3->Hide();
  wm::ActivateWindow(window2.get());
  EXPECT_EQ("110,110 100x100", window2->bounds().ToString());

  // Showing the 3rd will push the 2nd window left.
  window3->Show();
  wm::ActivateWindow(window3.get());
  EXPECT_EQ(0, window2->bounds().x());
  EXPECT_EQ(window3->GetRootWindow()->bounds().right(),
            window3->bounds().right());

  // Being a single window will retore the original location.
  window2->Hide();
  EXPECT_EQ("120,120 100x100", window3->bounds().ToString());
}

// Test that user placed windows go back to their user placement after the user
// closes all other windows.
TEST_F(WorkspaceControllerTest, TestUserHandledWindowRestore) {
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  gfx::Rect user_pos = gfx::Rect(16, 42, 640, 320);
  window1->SetBounds(user_pos);
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());

  window1_state->SetPreAutoManageWindowBounds(user_pos);
  gfx::Rect desktop_area = window1->parent()->bounds();

  // Create a second window to let the auto manager kick in.
  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));
  window1->Hide();
  window2->Hide();
  wm::GetWindowState(window1.get())->SetWindowPositionManaged(true);
  wm::GetWindowState(window2.get())->SetWindowPositionManaged(true);
  window1->Show();
  EXPECT_EQ(user_pos.ToString(), window1->bounds().ToString());
  window2->Show();

  // |window1| should be flush left and |window2| flush right.
  EXPECT_EQ("0," + base::NumberToString(user_pos.y()) + " 640x320",
            window1->bounds().ToString());
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window2->bounds().width()) +
          ",48 256x512",
      window2->bounds().ToString());
  window2->Hide();

  // After the other window get hidden the window has to move back to the
  // previous position and the bounds should still be set and unchanged.
  EXPECT_EQ(user_pos.ToString(), window1->bounds().ToString());
  ASSERT_TRUE(window1_state->pre_auto_manage_window_bounds());
  EXPECT_EQ(user_pos.ToString(),
            window1_state->pre_auto_manage_window_bounds()->ToString());
}

// Solo window should be restored to the bounds where a user moved to.
TEST_F(WorkspaceControllerTest, TestRestoreToUserModifiedBounds) {
  UpdateDisplay("400x300");
  gfx::Rect default_bounds(10, 0, 100, 100);
  std::unique_ptr<aura::Window> window1(
      CreateTestWindowInShellWithBounds(default_bounds));
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  window1->Hide();
  window1_state->SetWindowPositionManaged(true);
  window1->Show();
  // First window is centered.
  EXPECT_EQ("150,0 100x100", window1->bounds().ToString());
  std::unique_ptr<aura::Window> window2(
      CreateTestWindowInShellWithBounds(default_bounds));
  wm::WindowState* window2_state = wm::GetWindowState(window2.get());
  window2->Hide();
  window2_state->SetWindowPositionManaged(true);
  window2->Show();

  // Auto positioning pushes windows to each sides.
  EXPECT_EQ("0,0 100x100", window1->bounds().ToString());
  EXPECT_EQ("300,0 100x100", window2->bounds().ToString());

  window2->Hide();
  // Restores to the center.
  EXPECT_EQ("150,0 100x100", window1->bounds().ToString());

  // A user moved the window.
  std::unique_ptr<WindowResizer> resizer(
      CreateWindowResizer(window1.get(), gfx::Point(), HTCAPTION,
                          ::wm::WINDOW_MOVE_SOURCE_MOUSE)
          .release());
  gfx::Point location = resizer->GetInitialLocation();
  location.Offset(-50, 0);
  resizer->Drag(location, 0);
  resizer->CompleteDrag();

  window1_state->set_bounds_changed_by_user(true);
  window1->SetBounds(gfx::Rect(100, 0, 100, 100));

  window2->Show();
  EXPECT_EQ("0,0 100x100", window1->bounds().ToString());
  EXPECT_EQ("300,0 100x100", window2->bounds().ToString());

  // Window 1 should be restored to the user modified bounds.
  window2->Hide();
  EXPECT_EQ("100,0 100x100", window1->bounds().ToString());
}

// Test that a window from normal to minimize will repos the remaining.
TEST_F(WorkspaceControllerTest, ToMinimizeRepositionsRemaining) {
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  window1_state->SetWindowPositionManaged(true);
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();

  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  wm::WindowState* window2_state = wm::GetWindowState(window2.get());
  window2_state->SetWindowPositionManaged(true);
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));

  window1_state->Minimize();

  // |window2| should be centered now.
  EXPECT_TRUE(window2->IsVisible());
  EXPECT_TRUE(window2_state->IsNormalStateType());
  EXPECT_EQ(base::NumberToString(
                (desktop_area.width() - window2->bounds().width()) / 2) +
                ",48 256x512",
            window2->bounds().ToString());

  window1_state->Restore();
  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window1->bounds().width()) +
          ",32 640x320",
      window1->bounds().ToString());
  EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
}

// Test that minimizing an initially maximized window will repos the remaining.
TEST_F(WorkspaceControllerTest, MaxToMinRepositionsRemaining) {
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  window1_state->SetWindowPositionManaged(true);
  gfx::Rect desktop_area = window1->parent()->bounds();

  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  wm::WindowState* window2_state = wm::GetWindowState(window2.get());
  window2_state->SetWindowPositionManaged(true);
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));

  window1_state->Maximize();
  window1_state->Minimize();

  // |window2| should be centered now.
  EXPECT_TRUE(window2->IsVisible());
  EXPECT_TRUE(window2_state->IsNormalStateType());
  EXPECT_EQ(base::NumberToString(
                (desktop_area.width() - window2->bounds().width()) / 2) +
                ",48 256x512",
            window2->bounds().ToString());
}

// Test that nomral, maximize, minimizing will repos the remaining.
TEST_F(WorkspaceControllerTest, NormToMaxToMinRepositionsRemaining) {
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  window1_state->SetWindowPositionManaged(true);
  gfx::Rect desktop_area = window1->parent()->bounds();

  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  wm::WindowState* window2_state = wm::GetWindowState(window2.get());
  window2_state->SetWindowPositionManaged(true);
  window2->SetBounds(gfx::Rect(32, 40, 256, 512));

  // Trigger the auto window placement function by showing (and hiding) it.
  window1->Hide();
  window1->Show();

  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window1->bounds().width()) +
          ",32 640x320",
      window1->bounds().ToString());
  EXPECT_EQ("0,40 256x512", window2->bounds().ToString());

  window1_state->Maximize();
  window1_state->Minimize();

  // |window2| should be centered now.
  EXPECT_TRUE(window2->IsVisible());
  EXPECT_TRUE(window2_state->IsNormalStateType());
  EXPECT_EQ(base::NumberToString(
                (desktop_area.width() - window2->bounds().width()) / 2) +
                ",40 256x512",
            window2->bounds().ToString());
}

// Test that nomral, maximize, normal will repos the remaining.
TEST_F(WorkspaceControllerTest, NormToMaxToNormRepositionsRemaining) {
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
  window1_state->SetWindowPositionManaged(true);
  gfx::Rect desktop_area = window1->parent()->bounds();

  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  wm::GetWindowState(window2.get())->SetWindowPositionManaged(true);
  window2->SetBounds(gfx::Rect(32, 40, 256, 512));

  // Trigger the auto window placement function by showing (and hiding) it.
  window1->Hide();
  window1->Show();

  // |window1| should be flush right and |window3| flush left.
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window1->bounds().width()) +
          ",32 640x320",
      window1->bounds().ToString());
  EXPECT_EQ("0,40 256x512", window2->bounds().ToString());

  window1_state->Maximize();
  window1_state->Restore();

  // |window1| should be flush right and |window2| flush left.
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window1->bounds().width()) +
          ",32 640x320",
      window1->bounds().ToString());
  EXPECT_EQ("0,40 256x512", window2->bounds().ToString());
}

// Test that animations are triggered.
TEST_F(WorkspaceControllerTest, AnimatedNormToMaxToNormRepositionsRemaining) {
  ui::ScopedAnimationDurationScaleMode test_duration_mode(
      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(0));
  window1->Hide();
  window1->SetBounds(gfx::Rect(16, 32, 640, 320));
  gfx::Rect desktop_area = window1->parent()->bounds();
  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(1));
  window2->Hide();
  window2->SetBounds(gfx::Rect(32, 48, 256, 512));

  wm::GetWindowState(window1.get())->SetWindowPositionManaged(true);
  wm::GetWindowState(window2.get())->SetWindowPositionManaged(true);
  // Make sure nothing is animating.
  window1->layer()->GetAnimator()->StopAnimating();
  window2->layer()->GetAnimator()->StopAnimating();
  window2->Show();

  // The second window should now animate.
  EXPECT_FALSE(window1->layer()->GetAnimator()->is_animating());
  EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());
  window2->layer()->GetAnimator()->StopAnimating();

  window1->Show();
  EXPECT_TRUE(window1->layer()->GetAnimator()->is_animating());
  EXPECT_TRUE(window2->layer()->GetAnimator()->is_animating());

  window1->layer()->GetAnimator()->StopAnimating();
  window2->layer()->GetAnimator()->StopAnimating();
  // |window1| should be flush right and |window2| flush left.
  EXPECT_EQ(
      base::NumberToString(desktop_area.width() - window1->bounds().width()) +
          ",32 640x320",
      window1->bounds().ToString());
  EXPECT_EQ("0,48 256x512", window2->bounds().ToString());
}

// This tests simulates a browser and an app and verifies the ordering of the
// windows and layers doesn't get out of sync as various operations occur. Its
// really testing code in FocusController, but easier to simulate here. Just as
// with a real browser the browser here has a transient child window
// (corresponds to the status bubble).
TEST_F(WorkspaceControllerTest, VerifyLayerOrdering) {
  std::unique_ptr<Window> browser(aura::test::CreateTestWindowWithDelegate(
      NULL, aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(5, 6, 7, 8), NULL));
  browser->SetName("browser");
  ParentWindowInPrimaryRootWindow(browser.get());
  browser->Show();
  wm::ActivateWindow(browser.get());

  // |status_bubble| is made a transient child of |browser| and as a result
  // owned by |browser|.
  aura::test::TestWindowDelegate* status_bubble_delegate =
      aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate();
  status_bubble_delegate->set_can_focus(false);
  Window* status_bubble = aura::test::CreateTestWindowWithDelegate(
      status_bubble_delegate, aura::client::WINDOW_TYPE_POPUP,
      gfx::Rect(5, 6, 7, 8), NULL);
  ::wm::AddTransientChild(browser.get(), status_bubble);
  ParentWindowInPrimaryRootWindow(status_bubble);
  status_bubble->SetName("status_bubble");

  std::unique_ptr<Window> app(aura::test::CreateTestWindowWithDelegate(
      NULL, aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(5, 6, 7, 8), NULL));
  app->SetName("app");
  ParentWindowInPrimaryRootWindow(app.get());

  aura::Window* parent = browser->parent();

  app->Show();
  wm::ActivateWindow(app.get());
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Minimize the app, focus should go the browser.
  app->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_TRUE(wm::IsActiveWindow(browser.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Minimize the browser (neither windows are focused).
  browser->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
  EXPECT_FALSE(wm::IsActiveWindow(browser.get()));
  EXPECT_FALSE(wm::IsActiveWindow(app.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Show the browser (which should restore it).
  browser->Show();
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Activate the browser.
  ash::wm::ActivateWindow(browser.get());
  EXPECT_TRUE(wm::IsActiveWindow(browser.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Restore the app. This differs from above code for |browser| as internally
  // the app code does this. Restoring this way or using Show() should not make
  // a difference.
  app->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));

  // Activate the app.
  ash::wm::ActivateWindow(app.get());
  EXPECT_TRUE(wm::IsActiveWindow(app.get()));
  EXPECT_EQ(GetWindowNames(parent), GetLayerNames(parent));
}

// Test that minimizing and restoring a snapped window should restore to the
// snapped bounds. When a window is created and snapped, it must be a
// user-initiated operation, no need to do rearrangement for restoring this
// window (crbug.com/692175).
TEST_F(WorkspaceControllerTest, RestoreMinimizedSnappedWindow) {
  // Create an auto-positioned window.
  std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->SetWindowPositionManaged(true);
  window->SetBounds(gfx::Rect(10, 20, 100, 200));
  window->Show();

  // Left snap |window|.
  EXPECT_FALSE(window_state->bounds_changed_by_user());
  const wm::WMEvent snap_left(wm::WM_EVENT_SNAP_LEFT);
  window_state->OnWMEvent(&snap_left);
  const gfx::Rect work_area =
      display::Screen::GetScreen()
          ->GetDisplayNearestPoint(window->bounds().origin())
          .work_area();
  gfx::Rect snapped_bounds(work_area.x(), work_area.y(), work_area.width() / 2,
                           work_area.height());
  EXPECT_EQ(snapped_bounds, window->bounds());
  EXPECT_TRUE(window_state->bounds_changed_by_user());

  // Minimize and Restore |window|, the restored bounds should be equal to the
  // bounds of left snapped state.
  window_state->Minimize();
  window_state->Restore();
  EXPECT_EQ(snapped_bounds, window->bounds());
}

// Verifies that a new maximized window becomes visible after its activation
// is requested, even though it does not become activated because a system
// modal window is active.
TEST_F(WorkspaceControllerTest, SwitchFromModal) {
  std::unique_ptr<Window> modal_window(CreateTestWindowUnparented());
  modal_window->SetBounds(gfx::Rect(10, 11, 21, 22));
  modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM);
  ParentWindowInPrimaryRootWindow(modal_window.get());
  modal_window->Show();
  wm::ActivateWindow(modal_window.get());

  std::unique_ptr<Window> maximized_window(CreateTestWindow());
  maximized_window->SetProperty(aura::client::kShowStateKey,
                                ui::SHOW_STATE_MAXIMIZED);
  maximized_window->Show();
  wm::ActivateWindow(maximized_window.get());
  EXPECT_TRUE(maximized_window->IsVisible());
}

// Verifies that when dragging a window autohidden shelf stays hidden during
// and after the drag.
TEST_F(WorkspaceControllerTest, DragWindowKeepsShelfAutohidden) {
  aura::test::TestWindowDelegate delegate;
  delegate.set_window_component(HTCAPTION);
  std::unique_ptr<Window> w1(aura::test::CreateTestWindowWithDelegate(
      &delegate, aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(5, 5, 100, 50),
      NULL));
  ParentWindowInPrimaryRootWindow(w1.get());

  Shelf* shelf = GetPrimaryShelf();
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());

  // Drag very little.
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
                                     gfx::Point());
  generator.MoveMouseTo(10, 10);
  generator.PressLeftButton();
  generator.MoveMouseTo(12, 12);

  // Shelf should be hidden during and after the drag.
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
  generator.ReleaseLeftButton();
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
}

// Verifies that events are targeted properly just outside the window edges.
TEST_F(WorkspaceControllerTest, WindowEdgeHitTest) {
  aura::test::TestWindowDelegate d_first, d_second;
  std::unique_ptr<Window> first(aura::test::CreateTestWindowWithDelegate(
      &d_first, 123, gfx::Rect(20, 10, 100, 50), NULL));
  ParentWindowInPrimaryRootWindow(first.get());
  first->Show();

  std::unique_ptr<Window> second(aura::test::CreateTestWindowWithDelegate(
      &d_second, 234, gfx::Rect(30, 40, 40, 10), NULL));
  ParentWindowInPrimaryRootWindow(second.get());
  second->Show();

  aura::Window* root = first->GetRootWindow();
  ui::EventTargeter* targeter =
      root->GetHost()->dispatcher()->GetDefaultEventTargeter();

  // The windows overlap, and |second| is on top of |first|. Events targeted
  // slightly outside the edges of the |second| window should still be targeted
  // to |second| to allow resizing the windows easily.

  const int kNumPoints = 4;
  struct {
    const char* direction;
    gfx::Point location;
  } points[kNumPoints] = {
      {"left", gfx::Point(28, 45)},    // outside the left edge.
      {"top", gfx::Point(50, 38)},     // outside the top edge.
      {"right", gfx::Point(72, 45)},   // outside the right edge.
      {"bottom", gfx::Point(50, 52)},  // outside the bottom edge.
  };
  // Do two iterations, first without any transform on |second|, and the second
  // time after applying some transform on |second| so that it doesn't get
  // targeted.
  for (int times = 0; times < 2; ++times) {
    SCOPED_TRACE(times == 0 ? "Without transform" : "With transform");
    aura::Window* expected_target = times == 0 ? second.get() : first.get();
    for (int i = 0; i < kNumPoints; ++i) {
      SCOPED_TRACE(points[i].direction);
      const gfx::Point& location = points[i].location;
      ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, location, location,
                           ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
      ui::EventTarget* target = targeter->FindTargetForEvent(root, &mouse);
      EXPECT_EQ(expected_target, target);

      ui::TouchEvent touch(
          ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(),
          ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
      target = targeter->FindTargetForEvent(root, &touch);
      EXPECT_EQ(expected_target, target);
    }
    // Apply a transform on |second|. After the transform is applied, the window
    // should no longer be targeted.
    gfx::Transform transform;
    transform.Translate(70, 40);
    second->SetTransform(transform);
  }
}

}  // namespace ash
