// 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/frame/non_client_frame_view_ash.h"

#include <memory>

#include "ash/accelerators/accelerator_controller.h"
#include "ash/frame/header_view.h"
#include "ash/frame/wide_frame_view.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/caption_buttons/frame_caption_button_container_view.h"
#include "ash/public/cpp/default_frame_header.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h"
#include "ash/public/cpp/vector_icons/vector_icons.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h"
#include "ash/wm/wm_event.h"
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "services/ws/public/mojom/window_tree_constants.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_targeter.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/test_accelerator_target.h"
#include "ui/base/ui_base_features.h"
#include "ui/compositor/test/draw_waiter_for_test.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/caption_button_layout_constants.h"
#include "ui/views/window/frame_caption_button.h"
#include "ui/views/window/vector_icons/vector_icons.h"
#include "ui/wm/core/window_util.h"

namespace ash {

// A views::WidgetDelegate which uses a NonClientFrameViewAsh.
class NonClientFrameViewAshTestWidgetDelegate
    : public views::WidgetDelegateView {
 public:
  NonClientFrameViewAshTestWidgetDelegate() = default;
  ~NonClientFrameViewAshTestWidgetDelegate() override = default;

  views::NonClientFrameView* CreateNonClientFrameView(
      views::Widget* widget) override {
    non_client_frame_view_ = new NonClientFrameViewAsh(widget);
    return non_client_frame_view_;
  }

  int GetNonClientFrameViewTopBorderHeight() {
    return non_client_frame_view_->NonClientTopBorderHeight();
  }

  NonClientFrameViewAsh* non_client_frame_view() const {
    return non_client_frame_view_;
  }

  HeaderView* header_view() const {
    return non_client_frame_view_->header_view_;
  }

 private:
  // Not owned.
  NonClientFrameViewAsh* non_client_frame_view_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(NonClientFrameViewAshTestWidgetDelegate);
};

class TestWidgetConstraintsDelegate
    : public NonClientFrameViewAshTestWidgetDelegate {
 public:
  TestWidgetConstraintsDelegate() = default;
  ~TestWidgetConstraintsDelegate() override = default;

  // views::View:
  gfx::Size GetMinimumSize() const override { return minimum_size_; }

  gfx::Size GetMaximumSize() const override { return maximum_size_; }

  views::View* GetContentsView() override {
    // Set this instance as the contents view so that the maximum and minimum
    // size constraints will be used.
    return this;
  }

  // views::WidgetDelegate:
  bool CanMaximize() const override { return true; }

  bool CanMinimize() const override { return true; }

  void set_minimum_size(const gfx::Size& min_size) { minimum_size_ = min_size; }

  void set_maximum_size(const gfx::Size& max_size) { maximum_size_ = max_size; }

  const gfx::Rect& GetFrameCaptionButtonContainerViewBounds() {
    return non_client_frame_view()
        ->GetFrameCaptionButtonContainerViewForTest()
        ->bounds();
  }

  void EndFrameCaptionButtonContainerViewAnimations() {
    FrameCaptionButtonContainerView::TestApi test(
        non_client_frame_view()->GetFrameCaptionButtonContainerViewForTest());
    test.EndAnimations();
  }

  int GetTitleBarHeight() const {
    return non_client_frame_view()->NonClientTopBorderHeight();
  }

 private:
  gfx::Size minimum_size_;
  gfx::Size maximum_size_;

  DISALLOW_COPY_AND_ASSIGN(TestWidgetConstraintsDelegate);
};

using NonClientFrameViewAshTest = AshTestBase;

// Verifies the client view is not placed at a y location of 0.
TEST_F(NonClientFrameViewAshTest, ClientViewCorrectlyPlaced) {
  std::unique_ptr<views::Widget> widget =
      CreateTestWidget(new NonClientFrameViewAshTestWidgetDelegate);
  EXPECT_NE(0, widget->client_view()->bounds().y());
}

// Test that the height of the header is correct upon initially displaying
// the widget.
TEST_F(NonClientFrameViewAshTest, HeaderHeight) {
  NonClientFrameViewAshTestWidgetDelegate* delegate =
      new NonClientFrameViewAshTestWidgetDelegate;

  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  // The header should have enough room for the window controls. The
  // header/content separator line overlays the window controls.
  EXPECT_EQ(views::GetCaptionButtonLayoutSize(
                views::CaptionButtonLayoutSize::kNonBrowserCaption)
                .height(),
            delegate->non_client_frame_view()->GetHeaderView()->height());
}

// Regression test for https://crbug.com/839955
TEST_F(NonClientFrameViewAshTest, ActiveStateOfButtonMatchesWidget) {
  NonClientFrameViewAshTestWidgetDelegate* delegate =
      new NonClientFrameViewAshTestWidgetDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
  FrameCaptionButtonContainerView::TestApi test_api(
      delegate->non_client_frame_view()
          ->GetHeaderView()
          ->caption_button_container());

  widget->Show();
  EXPECT_TRUE(widget->IsActive());
  // The paint state doesn't change till the next paint.
  ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
  EXPECT_TRUE(test_api.size_button()->paint_as_active());

  // Activate a different widget so the original one loses activation.
  std::unique_ptr<views::Widget> widget2 =
      CreateTestWidget(new NonClientFrameViewAshTestWidgetDelegate);
  widget2->Show();
  ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());

  EXPECT_FALSE(widget->IsActive());
  EXPECT_FALSE(test_api.size_button()->paint_as_active());
}

// Verify that NonClientFrameViewAsh returns the correct minimum and maximum
// frame sizes when the client view does not specify any size constraints.
TEST_F(NonClientFrameViewAshTest, NoSizeConstraints) {
  TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  gfx::Size min_frame_size = non_client_frame_view->GetMinimumSize();
  gfx::Size max_frame_size = non_client_frame_view->GetMaximumSize();

  EXPECT_EQ(delegate->GetTitleBarHeight(), min_frame_size.height());

  // A width and height constraint of 0 denotes unbounded.
  EXPECT_EQ(0, max_frame_size.width());
  EXPECT_EQ(0, max_frame_size.height());
}

// Verify that NonClientFrameViewAsh returns the correct minimum and maximum
// frame sizes when the client view specifies size constraints.
TEST_F(NonClientFrameViewAshTest, MinimumAndMaximumSize) {
  gfx::Size min_client_size(500, 500);
  gfx::Size max_client_size(800, 800);
  TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
  delegate->set_minimum_size(min_client_size);
  delegate->set_maximum_size(max_client_size);
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  gfx::Size min_frame_size = non_client_frame_view->GetMinimumSize();
  gfx::Size max_frame_size = non_client_frame_view->GetMaximumSize();

  EXPECT_EQ(min_client_size.width(), min_frame_size.width());
  EXPECT_EQ(max_client_size.width(), max_frame_size.width());
  EXPECT_EQ(min_client_size.height() + delegate->GetTitleBarHeight(),
            min_frame_size.height());
  EXPECT_EQ(max_client_size.height() + delegate->GetTitleBarHeight(),
            max_frame_size.height());
}

// Verify that NonClientFrameViewAsh returns the correct minimum frame size when
// the kMinimumSize property is set.
TEST_F(NonClientFrameViewAshTest, HonorsMinimumSizeProperty) {
  const gfx::Size min_client_size(500, 500);
  TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
  delegate->set_minimum_size(min_client_size);
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  // Update the native window's minimum size property.
  const gfx::Size min_window_size(600, 700);
  widget->GetNativeWindow()->SetProperty(aura::client::kMinimumSize,
                                         new gfx::Size(min_window_size));

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  const gfx::Size min_frame_size = non_client_frame_view->GetMinimumSize();

  EXPECT_EQ(min_window_size, min_frame_size);
}

// Verify that NonClientFrameViewAsh updates the avatar icon based on the
// avatar icon window property.
TEST_F(NonClientFrameViewAshTest, AvatarIcon) {
  TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  EXPECT_FALSE(non_client_frame_view->GetAvatarIconViewForTest());

  // Avatar image becomes available.
  widget->GetNativeWindow()->SetProperty(
      aura::client::kAvatarIconKey,
      new gfx::ImageSkia(gfx::test::CreateImage(27, 27).AsImageSkia()));
  EXPECT_TRUE(non_client_frame_view->GetAvatarIconViewForTest());

  // Avatar image is gone; the ImageView for the avatar icon should be
  // removed.
  widget->GetNativeWindow()->ClearProperty(aura::client::kAvatarIconKey);
  EXPECT_FALSE(non_client_frame_view->GetAvatarIconViewForTest());
}

// The visibility of the size button is updated when tablet mode is toggled.
// Verify that the layout of the HeaderView is updated for the size button's
// new visibility.
TEST_F(NonClientFrameViewAshTest, HeaderViewNotifiedOfChildSizeChange) {
  TestWidgetConstraintsDelegate* delegate = new TestWidgetConstraintsDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(
      delegate, kShellWindowId_DefaultContainer, gfx::Rect(0, 0, 400, 500));

  const gfx::Rect initial =
      delegate->GetFrameCaptionButtonContainerViewBounds();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  delegate->EndFrameCaptionButtonContainerViewAnimations();
  const gfx::Rect tablet_mode_bounds =
      delegate->GetFrameCaptionButtonContainerViewBounds();
  EXPECT_GT(initial.width(), tablet_mode_bounds.width());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  delegate->EndFrameCaptionButtonContainerViewAnimations();
  const gfx::Rect after_restore =
      delegate->GetFrameCaptionButtonContainerViewBounds();
  EXPECT_EQ(initial, after_restore);
}

// Tests that a window is minimized, toggling tablet mode doesn't trigger
// caption button update (https://crbug.com/822890).
TEST_F(NonClientFrameViewAshTest, ToggleTabletModeOnMinimizedWindow) {
  NonClientFrameViewAshTestWidgetDelegate* delegate =
      new NonClientFrameViewAshTestWidgetDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
  FrameCaptionButtonContainerView::TestApi test(
      delegate->non_client_frame_view()
          ->GetHeaderView()
          ->caption_button_container());
  widget->Maximize();

  // Restore icon for size button in maximized window state. Compare by name
  // because the address may not be the same for different build targets in the
  // component build.
  EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
               test.size_button()->icon_definition_for_test()->name);
  widget->Minimize();

  // Enter and exit tablet mode while the window is minimized.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);

  // When unminimizing in non-tablet mode, size button should match with
  // maximized window state, which is restore icon.
  ::wm::Unminimize(widget->GetNativeWindow());
  EXPECT_TRUE(widget->IsMaximized());
  EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
               test.size_button()->icon_definition_for_test()->name);
}

// Verify that when in tablet mode with a maximized window, the height of the
// header is zero.
TEST_F(NonClientFrameViewAshTest, FrameHiddenInTabletModeForMaximizedWindows) {
  NonClientFrameViewAshTestWidgetDelegate* delegate =
      new NonClientFrameViewAshTestWidgetDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
  widget->Maximize();

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
}

// Verify that when in tablet mode with a non maximized window, the height of
// the header is non zero.
TEST_F(NonClientFrameViewAshTest,
       FrameShownInTabletModeForNonMaximizedWindows) {
  auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_EQ(views::GetCaptionButtonLayoutSize(
                views::CaptionButtonLayoutSize::kNonBrowserCaption)
                .height(),
            delegate->GetNonClientFrameViewTopBorderHeight());
}

// Verify that if originally in fullscreen mode, and enter tablet mode, the
// height of the header remains zero.
TEST_F(NonClientFrameViewAshTest,
       FrameRemainsHiddenInTabletModeWhenTogglingFullscreen) {
  NonClientFrameViewAshTestWidgetDelegate* delegate =
      new NonClientFrameViewAshTestWidgetDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  widget->SetFullscreen(true);
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());
}

TEST_F(NonClientFrameViewAshTest, OpeningAppsInTabletMode) {
  auto* delegate = new TestWidgetConstraintsDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
  widget->Maximize();

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());

  // Verify that after minimizing and showing the widget, the height of the
  // header is zero.
  widget->Minimize();
  widget->Show();
  EXPECT_TRUE(widget->IsMaximized());
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());

  // Verify that when we toggle maximize, the header is shown. For example,
  // maximized can be toggled in tablet mode by using the accessibility
  // keyboard.
  wm::WMEvent event(wm::WM_EVENT_TOGGLE_MAXIMIZE);
  wm::GetWindowState(widget->GetNativeWindow())->OnWMEvent(&event);
  EXPECT_EQ(0, delegate->GetNonClientFrameViewTopBorderHeight());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  EXPECT_EQ(views::GetCaptionButtonLayoutSize(
                views::CaptionButtonLayoutSize::kNonBrowserCaption)
                .height(),
            delegate->GetNonClientFrameViewTopBorderHeight());
}

// Test if creating a new window in tablet mode uses maximzied state
// and immersive mode.
TEST_F(NonClientFrameViewAshTest, GetPreferredOnScreenHeightInTabletMaximzied) {
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  auto* delegate = new TestWidgetConstraintsDelegate;
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
  auto* frame_view = static_cast<ash::NonClientFrameViewAsh*>(
      widget->non_client_view()->frame_view());
  auto* header_view = frame_view->GetHeaderView();
  ASSERT_TRUE(widget->IsMaximized());
  EXPECT_TRUE(header_view->in_immersive_mode());
  static_cast<ImmersiveFullscreenControllerDelegate*>(header_view)
      ->SetVisibleFraction(0.5);
  // The height should be ~(33 *.5)
  EXPECT_NEAR(16, header_view->GetPreferredOnScreenHeight(), 1);
  static_cast<ImmersiveFullscreenControllerDelegate*>(header_view)
      ->SetVisibleFraction(0.0);
  EXPECT_EQ(0, header_view->GetPreferredOnScreenHeight());
}

// Verify windows that are minimized and then entered into tablet mode will have
// no header when unminimized in tablet mode.
TEST_F(NonClientFrameViewAshTest, MinimizedWindowsInTabletMode) {
  std::unique_ptr<views::Widget> widget =
      CreateTestWidget(new NonClientFrameViewAshTestWidgetDelegate);
  widget->GetNativeWindow()->SetProperty(aura::client::kResizeBehaviorKey,
                                         ws::mojom::kResizeBehaviorCanMaximize);
  widget->Maximize();
  widget->Minimize();
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  widget->Show();
  EXPECT_EQ(widget->non_client_view()->bounds(),
            widget->client_view()->bounds());
}

TEST_F(NonClientFrameViewAshTest, HeaderVisibilityInOverviewMode) {
  auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
  std::unique_ptr<views::Widget> widget = CreateTestWidget(
      delegate, kShellWindowId_DefaultContainer, gfx::Rect(0, 0, 400, 500));

  // Verify the header is not painted in overview mode and painted when not in
  // overview mode.
  Shell::Get()->window_selector_controller()->ToggleOverview();
  EXPECT_FALSE(delegate->header_view()->should_paint());

  Shell::Get()->window_selector_controller()->ToggleOverview();
  EXPECT_TRUE(delegate->header_view()->should_paint());
}

TEST_F(NonClientFrameViewAshTest, HeaderVisibilityInSplitview) {
  auto create_widget = [](NonClientFrameViewAshTestWidgetDelegate* delegate) {
    std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
    // Windows need to be resizable and maximizable to be used in splitview.
    widget->GetNativeWindow()->SetProperty(
        aura::client::kResizeBehaviorKey,
        ws::mojom::kResizeBehaviorCanMaximize |
            ws::mojom::kResizeBehaviorCanResize);
    return widget;
  };

  auto* delegate1 = new NonClientFrameViewAshTestWidgetDelegate();
  auto widget1 = create_widget(delegate1);
  auto* delegate2 = new NonClientFrameViewAshTestWidgetDelegate();
  auto widget2 = create_widget(delegate2);

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);

  // Verify that when one window is snapped, the header is drawn for the snapped
  // window, but not drawn for the window still in overview.
  Shell::Get()->window_selector_controller()->ToggleOverview();
  Shell::Get()->split_view_controller()->SnapWindow(widget1->GetNativeWindow(),
                                                    SplitViewController::LEFT);
  EXPECT_TRUE(delegate1->header_view()->should_paint());
  EXPECT_EQ(0, delegate1->GetNonClientFrameViewTopBorderHeight());
  EXPECT_FALSE(delegate2->header_view()->should_paint());

  // Verify that when both windows are snapped, the header is drawn for both.
  Shell::Get()->split_view_controller()->SnapWindow(widget2->GetNativeWindow(),
                                                    SplitViewController::RIGHT);
  EXPECT_TRUE(delegate1->header_view()->should_paint());
  EXPECT_TRUE(delegate2->header_view()->should_paint());
  EXPECT_EQ(0, delegate1->GetNonClientFrameViewTopBorderHeight());
  EXPECT_EQ(0, delegate2->GetNonClientFrameViewTopBorderHeight());

  // Toggle overview mode so we return back to left snapped mode. Verify that
  // the header is again drawn for the snapped window, but not for the unsnapped
  // window.
  Shell::Get()->window_selector_controller()->ToggleOverview();
  ASSERT_EQ(SplitViewController::LEFT_SNAPPED,
            Shell::Get()->split_view_controller()->state());
  EXPECT_TRUE(delegate1->header_view()->should_paint());
  EXPECT_EQ(0, delegate1->GetNonClientFrameViewTopBorderHeight());
  EXPECT_FALSE(delegate2->header_view()->should_paint());

  Shell::Get()->split_view_controller()->EndSplitView();
}

namespace {

class TestButtonModel : public CaptionButtonModel {
 public:
  TestButtonModel() = default;
  ~TestButtonModel() override = default;

  void set_zoom_mode(bool zoom_mode) { zoom_mode_ = zoom_mode; }

  void SetVisible(views::CaptionButtonIcon type, bool visible) {
    if (visible)
      visible_buttons_.insert(type);
    else
      visible_buttons_.erase(type);
  }

  void SetEnabled(views::CaptionButtonIcon type, bool enabled) {
    if (enabled)
      enabled_buttons_.insert(type);
    else
      enabled_buttons_.erase(type);
  }

  // CaptionButtonModel::
  bool IsVisible(views::CaptionButtonIcon type) const override {
    return visible_buttons_.count(type);
  }
  bool IsEnabled(views::CaptionButtonIcon type) const override {
    return enabled_buttons_.count(type);
  }
  bool InZoomMode() const override { return zoom_mode_; }

 private:
  base::flat_set<views::CaptionButtonIcon> visible_buttons_;
  base::flat_set<views::CaptionButtonIcon> enabled_buttons_;
  bool zoom_mode_ = false;

  DISALLOW_COPY_AND_ASSIGN(TestButtonModel);
};

}  // namespace

TEST_F(NonClientFrameViewAshTest, BackButton) {
  ash::AcceleratorController* controller =
      ash::Shell::Get()->accelerator_controller();
  std::unique_ptr<TestButtonModel> model = std::make_unique<TestButtonModel>();
  TestButtonModel* model_ptr = model.get();

  auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
  std::unique_ptr<views::Widget> widget = CreateTestWidget(
      delegate, kShellWindowId_DefaultContainer, gfx::Rect(0, 0, 400, 500));

  ui::Accelerator accelerator_back_press(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
  accelerator_back_press.set_key_state(ui::Accelerator::KeyState::PRESSED);
  ui::TestAcceleratorTarget target_back_press;
  controller->Register({accelerator_back_press}, &target_back_press);

  ui::Accelerator accelerator_back_release(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
  accelerator_back_release.set_key_state(ui::Accelerator::KeyState::RELEASED);
  ui::TestAcceleratorTarget target_back_release;
  controller->Register({accelerator_back_release}, &target_back_release);

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  non_client_frame_view->SetCaptionButtonModel(std::move(model));

  HeaderView* header_view = non_client_frame_view->GetHeaderView();
  EXPECT_FALSE(header_view->GetBackButton());
  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(header_view->GetBackButton());
  EXPECT_FALSE(header_view->GetBackButton()->enabled());

  // Back button is disabled, so clicking on it should not should
  // generate back key sequence.
  ui::test::EventGenerator* generator = GetEventGenerator();
  generator->MoveMouseTo(
      header_view->GetBackButton()->GetBoundsInScreen().CenterPoint());
  generator->ClickLeftButton();
  EXPECT_EQ(0, target_back_press.accelerator_count());
  EXPECT_EQ(0, target_back_release.accelerator_count());

  model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_BACK, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(header_view->GetBackButton());
  EXPECT_TRUE(header_view->GetBackButton()->enabled());

  // Back button is now enabled, so clicking on it should generate
  // back key sequence.
  generator->MoveMouseTo(
      header_view->GetBackButton()->GetBoundsInScreen().CenterPoint());

  generator->ClickLeftButton();
  EXPECT_EQ(1, target_back_press.accelerator_count());
  EXPECT_EQ(1, target_back_release.accelerator_count());

  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, false);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_FALSE(header_view->GetBackButton());
}

// Make sure that client view occupies the entire window when the
// frame is hidden.
TEST_F(NonClientFrameViewAshTest, FrameVisibility) {
  NonClientFrameViewAshTestWidgetDelegate* delegate =
      new NonClientFrameViewAshTestWidgetDelegate;
  gfx::Rect window_bounds(10, 10, 200, 100);
  std::unique_ptr<views::Widget> widget = CreateTestWidget(
      delegate, kShellWindowId_DefaultContainer, window_bounds);

  // The height is smaller by the top border height.
  gfx::Size client_bounds(200, 68);
  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  EXPECT_EQ(client_bounds, widget->client_view()->GetLocalBounds().size());

  non_client_frame_view->SetVisible(false);
  widget->GetRootView()->Layout();
  EXPECT_EQ(gfx::Size(200, 100),
            widget->client_view()->GetLocalBounds().size());
  EXPECT_FALSE(widget->non_client_view()->frame_view()->visible());
  EXPECT_EQ(
      window_bounds,
      non_client_frame_view->GetClientBoundsForWindowBounds(window_bounds));

  non_client_frame_view->SetVisible(true);
  widget->GetRootView()->Layout();
  EXPECT_EQ(client_bounds, widget->client_view()->GetLocalBounds().size());
  EXPECT_TRUE(widget->non_client_view()->frame_view()->visible());
  EXPECT_EQ(32, delegate->GetNonClientFrameViewTopBorderHeight());
  EXPECT_EQ(
      gfx::Rect(gfx::Point(10, 42), client_bounds),
      non_client_frame_view->GetClientBoundsForWindowBounds(window_bounds));
}

TEST_F(NonClientFrameViewAshTest, CustomButtonModel) {
  std::unique_ptr<TestButtonModel> model = std::make_unique<TestButtonModel>();
  TestButtonModel* model_ptr = model.get();

  auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  non_client_frame_view->SetCaptionButtonModel(std::move(model));

  HeaderView* header_view = non_client_frame_view->GetHeaderView();
  FrameCaptionButtonContainerView::TestApi test_api(
      header_view->caption_button_container());

  // CLOSE buttion is always visible and enabled.
  EXPECT_TRUE(test_api.close_button());
  EXPECT_TRUE(test_api.close_button()->visible());
  EXPECT_TRUE(test_api.close_button()->enabled());

  EXPECT_FALSE(test_api.minimize_button()->visible());
  EXPECT_FALSE(test_api.size_button()->visible());
  EXPECT_FALSE(test_api.menu_button()->visible());

  // Back button
  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_BACK, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(header_view->GetBackButton()->visible());
  EXPECT_FALSE(header_view->GetBackButton()->enabled());

  model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_BACK, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(header_view->GetBackButton()->enabled());

  // size button
  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(test_api.size_button()->visible());
  EXPECT_FALSE(test_api.size_button()->enabled());

  model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(test_api.size_button()->enabled());

  // minimize button
  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_MINIMIZE, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(test_api.minimize_button()->visible());
  EXPECT_FALSE(test_api.minimize_button()->enabled());

  model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_MINIMIZE, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(test_api.minimize_button()->enabled());

  // menu button
  model_ptr->SetVisible(views::CAPTION_BUTTON_ICON_MENU, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(test_api.menu_button()->visible());
  EXPECT_FALSE(test_api.menu_button()->enabled());

  model_ptr->SetEnabled(views::CAPTION_BUTTON_ICON_MENU, true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_TRUE(test_api.menu_button()->enabled());

  // zoom button
  EXPECT_STREQ(views::kWindowControlMaximizeIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);
  model_ptr->set_zoom_mode(true);
  non_client_frame_view->SizeConstraintsChanged();
  EXPECT_STREQ(kWindowControlZoomIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);
  widget->Maximize();
  EXPECT_STREQ(kWindowControlDezoomIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);
}

TEST_F(NonClientFrameViewAshTest, WideFrame) {
  auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
  std::unique_ptr<views::Widget> widget = CreateTestWidget(
      delegate, kShellWindowId_DefaultContainer, gfx::Rect(100, 0, 400, 500));

  NonClientFrameViewAsh* non_client_frame_view =
      delegate->non_client_frame_view();
  HeaderView* header_view = non_client_frame_view->GetHeaderView();
  widget->Maximize();

  std::unique_ptr<WideFrameView> wide_frame_view =
      std::make_unique<WideFrameView>(widget.get());
  wide_frame_view->GetWidget()->Show();

  HeaderView* wide_header_view = wide_frame_view->header_view();
  display::Screen* screen = display::Screen::GetScreen();

  const gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
  gfx::Rect frame_bounds =
      wide_frame_view->GetWidget()->GetWindowBoundsInScreen();
  EXPECT_EQ(work_area.width(), frame_bounds.width());
  EXPECT_EQ(work_area.origin(), frame_bounds.origin());
  EXPECT_FALSE(header_view->should_paint());
  EXPECT_TRUE(wide_header_view->should_paint());

  Shell::Get()->window_selector_controller()->ToggleOverview();
  EXPECT_FALSE(wide_header_view->should_paint());
  Shell::Get()->window_selector_controller()->ToggleOverview();
  EXPECT_TRUE(wide_header_view->should_paint());

  // Test immersive.
  ImmersiveFullscreenController controller(Shell::Get()->immersive_context());
  wide_frame_view->Init(&controller);
  EXPECT_FALSE(wide_header_view->in_immersive_mode());
  EXPECT_FALSE(header_view->in_immersive_mode());

  ImmersiveFullscreenController::EnableForWidget(widget.get(), true);
  EXPECT_TRUE(header_view->in_immersive_mode());
  EXPECT_TRUE(wide_header_view->in_immersive_mode());
  // The height should be ~(33 *.5)
  wide_header_view->SetVisibleFraction(0.5);
  EXPECT_NEAR(16, wide_header_view->GetPreferredOnScreenHeight(), 1);

  // Make sure the frame can be revaled outside of the target window.
  EXPECT_FALSE(ImmersiveFullscreenControllerTestApi(&controller)
                   .IsTopEdgeHoverTimerRunning());
  ui::test::EventGenerator* generator = GetEventGenerator();
  generator->MoveMouseTo(gfx::Point(10, 0));
  generator->MoveMouseBy(1, 0);
  EXPECT_TRUE(ImmersiveFullscreenControllerTestApi(&controller)
                  .IsTopEdgeHoverTimerRunning());

  generator->MoveMouseTo(gfx::Point(10, 10));
  generator->MoveMouseBy(1, 0);
  EXPECT_FALSE(ImmersiveFullscreenControllerTestApi(&controller)
                   .IsTopEdgeHoverTimerRunning());

  generator->MoveMouseTo(gfx::Point(600, 0));
  generator->MoveMouseBy(1, 0);
  EXPECT_TRUE(ImmersiveFullscreenControllerTestApi(&controller)
                  .IsTopEdgeHoverTimerRunning());

  ImmersiveFullscreenController::EnableForWidget(widget.get(), false);
  EXPECT_FALSE(header_view->in_immersive_mode());
  EXPECT_FALSE(wide_header_view->in_immersive_mode());
  // visible fraction should be ignored in non immersive.
  wide_header_view->SetVisibleFraction(0.5);
  EXPECT_EQ(32, wide_header_view->GetPreferredOnScreenHeight());

  UpdateDisplay("1234x800");
  EXPECT_EQ(1234,
            wide_frame_view->GetWidget()->GetWindowBoundsInScreen().width());

  // Double Click
  EXPECT_TRUE(widget->IsMaximized());
  generator->MoveMouseToCenterOf(
      wide_header_view->GetWidget()->GetNativeWindow());
  generator->DoubleClickLeftButton();
  EXPECT_FALSE(widget->IsMaximized());
}

TEST_F(NonClientFrameViewAshTest, WideFrameButton) {
  auto* delegate = new NonClientFrameViewAshTestWidgetDelegate();
  std::unique_ptr<views::Widget> widget = CreateTestWidget(
      delegate, kShellWindowId_DefaultContainer, gfx::Rect(100, 0, 400, 500));

  std::unique_ptr<WideFrameView> wide_frame_view =
      std::make_unique<WideFrameView>(widget.get());
  wide_frame_view->GetWidget()->Show();
  HeaderView* header_view = wide_frame_view->header_view();
  FrameCaptionButtonContainerView::TestApi test_api(
      header_view->caption_button_container());

  EXPECT_STREQ(views::kWindowControlMaximizeIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);
  widget->Maximize();
  header_view->Layout();
  EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);

  widget->Restore();
  header_view->Layout();
  EXPECT_STREQ(views::kWindowControlMaximizeIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);

  widget->SetFullscreen(true);
  header_view->Layout();
  EXPECT_STREQ(views::kWindowControlRestoreIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);

  widget->SetFullscreen(false);
  header_view->Layout();
  EXPECT_STREQ(views::kWindowControlMaximizeIcon.name,
               test_api.size_button()->icon_definition_for_test()->name);
}

namespace {

class NonClientFrameViewAshFrameColorTest
    : public NonClientFrameViewAshTest,
      public testing::WithParamInterface<bool> {
 public:
  NonClientFrameViewAshFrameColorTest() = default;
  ~NonClientFrameViewAshFrameColorTest() override = default;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonClientFrameViewAshFrameColorTest);
};

class TestWidgetDelegate : public TestWidgetConstraintsDelegate {
 public:
  TestWidgetDelegate(bool custom) : custom_(custom) {}
  ~TestWidgetDelegate() override = default;

  // views::WidgetDelegate:
  views::NonClientFrameView* CreateNonClientFrameView(
      views::Widget* widget) override {
    if (custom_) {
      ash::wm::WindowState* window_state =
          ash::wm::GetWindowState(widget->GetNativeWindow());
      window_state->SetDelegate(std::make_unique<wm::WindowStateDelegate>());
    }
    return TestWidgetConstraintsDelegate::CreateNonClientFrameView(widget);
  }

 private:
  bool custom_;

  DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
};

}  // namespace

// Verify that NonClientFrameViewAsh updates the active color based on the
// ash::kFrameActiveColorKey window property.
TEST_P(NonClientFrameViewAshFrameColorTest, kFrameActiveColorKey) {
  TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  SkColor active_color =
      widget->GetNativeWindow()->GetProperty(ash::kFrameActiveColorKey);
  constexpr SkColor new_color = SK_ColorWHITE;
  EXPECT_NE(active_color, new_color);

  widget->GetNativeWindow()->SetProperty(ash::kFrameActiveColorKey, new_color);
  active_color =
      widget->GetNativeWindow()->GetProperty(ash::kFrameActiveColorKey);
  EXPECT_EQ(active_color, new_color);
  EXPECT_EQ(new_color,
            delegate->non_client_frame_view()->GetActiveFrameColorForTest());

  // Test that changing the property updates the caption button images.
  FrameCaptionButtonContainerView::TestApi test_api(
      delegate->non_client_frame_view()
          ->GetHeaderView()
          ->caption_button_container());
  ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
  gfx::ImageSkia original_icon_image = test_api.size_button()->icon_image();
  widget->GetNativeWindow()->SetProperty(ash::kFrameActiveColorKey,
                                         SK_ColorBLACK);
  ui::DrawWaiterForTest::WaitForCommit(widget->GetLayer()->GetCompositor());
  EXPECT_FALSE(original_icon_image.BackedBySameObjectAs(
      test_api.size_button()->icon_image()));
}

// Verify that NonClientFrameViewAsh updates the inactive color based on the
// ash::kFrameInactiveColorKey window property.
TEST_P(NonClientFrameViewAshFrameColorTest, KFrameInactiveColor) {
  TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);

  SkColor active_color =
      widget->GetNativeWindow()->GetProperty(ash::kFrameInactiveColorKey);
  constexpr SkColor new_color = SK_ColorWHITE;
  EXPECT_NE(active_color, new_color);

  widget->GetNativeWindow()->SetProperty(ash::kFrameInactiveColorKey,
                                         new_color);
  active_color =
      widget->GetNativeWindow()->GetProperty(ash::kFrameInactiveColorKey);
  EXPECT_EQ(active_color, new_color);
  EXPECT_EQ(new_color,
            delegate->non_client_frame_view()->GetInactiveFrameColorForTest());
}

// Verify that NonClientFrameViewAsh updates the active color based on the
// ash::kFrameActiveColorKey window property.
TEST_P(NonClientFrameViewAshFrameColorTest, WideFrameInitialColor) {
  TestWidgetDelegate* delegate = new TestWidgetDelegate(GetParam());
  std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
  aura::Window* window = widget->GetNativeWindow();
  SkColor active_color = window->GetProperty(ash::kFrameActiveColorKey);
  SkColor inactive_color = window->GetProperty(ash::kFrameInactiveColorKey);
  constexpr SkColor new_active_color = SK_ColorWHITE;
  constexpr SkColor new_inactive_color = SK_ColorBLACK;
  EXPECT_NE(active_color, new_active_color);
  EXPECT_NE(inactive_color, new_inactive_color);
  window->SetProperty(ash::kFrameActiveColorKey, new_active_color);
  window->SetProperty(ash::kFrameInactiveColorKey, new_inactive_color);

  std::unique_ptr<WideFrameView> wide_frame_view =
      std::make_unique<WideFrameView>(widget.get());
  HeaderView* wide_header_view = wide_frame_view->header_view();
  DefaultFrameHeader* header = wide_header_view->GetFrameHeader();
  EXPECT_EQ(new_active_color, header->active_frame_color_for_testing());
  EXPECT_EQ(new_inactive_color, header->inactive_frame_color_for_testing());
}

// Run frame color tests with and without custom wm::WindowStateDelegate.
INSTANTIATE_TEST_CASE_P(, NonClientFrameViewAshFrameColorTest, testing::Bool());

}  // namespace ash
