// 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 "ui/views/controls/menu/menu_controller.h"

#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/menu/menu_controller_delegate.h"
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/controls/menu/menu_host.h"
#include "ui/views/controls/menu/menu_host_root_view.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/test/menu_test_utils.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget_utils.h"

#if defined(USE_AURA)
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/drag_drop_client_observer.h"
#include "ui/aura/null_window_targeter.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/window.h"
#include "ui/views/controls/menu/menu_pre_target_handler.h"
#endif

#if defined(USE_X11)
#include "ui/events/test/events_test_utils_x11.h"
#include "ui/gfx/x/x11.h"
#endif

#if defined(OS_CHROMEOS)
#include "ui/base/ui_base_features.h"
#endif

namespace views {
namespace test {

namespace {

// Test implementation of MenuControllerDelegate that only reports the values
// called of OnMenuClosed.
class TestMenuControllerDelegate : public internal::MenuControllerDelegate {
 public:
  TestMenuControllerDelegate();
  ~TestMenuControllerDelegate() override {}

  int on_menu_closed_called() { return on_menu_closed_called_; }

  NotifyType on_menu_closed_notify_type() {
    return on_menu_closed_notify_type_;
  }

  MenuItemView* on_menu_closed_menu() { return on_menu_closed_menu_; }

  int on_menu_closed_mouse_event_flags() {
    return on_menu_closed_mouse_event_flags_;
  }

  // On a subsequent call to OnMenuClosed |controller| will be deleted.
  void set_on_menu_closed_callback(const base::Closure& callback) {
    on_menu_closed_callback_ = callback;
  }

  // internal::MenuControllerDelegate:
  void OnMenuClosed(NotifyType type,
                    MenuItemView* menu,
                    int mouse_event_flags) override;
  void SiblingMenuCreated(MenuItemView* menu) override;

 private:
  // Number of times OnMenuClosed has been called.
  int on_menu_closed_called_;

  // The values passed on the last call of OnMenuClosed.
  NotifyType on_menu_closed_notify_type_;
  MenuItemView* on_menu_closed_menu_;
  int on_menu_closed_mouse_event_flags_;

  // Optional callback triggered during OnMenuClosed
  base::Closure on_menu_closed_callback_;

  DISALLOW_COPY_AND_ASSIGN(TestMenuControllerDelegate);
};

TestMenuControllerDelegate::TestMenuControllerDelegate()
    : on_menu_closed_called_(0),
      on_menu_closed_notify_type_(NOTIFY_DELEGATE),
      on_menu_closed_menu_(nullptr),
      on_menu_closed_mouse_event_flags_(0),
      on_menu_closed_callback_() {}

void TestMenuControllerDelegate::OnMenuClosed(NotifyType type,
                                              MenuItemView* menu,
                                              int mouse_event_flags) {
  on_menu_closed_called_++;
  on_menu_closed_notify_type_ = type;
  on_menu_closed_menu_ = menu;
  on_menu_closed_mouse_event_flags_ = mouse_event_flags;
  if (!on_menu_closed_callback_.is_null())
    on_menu_closed_callback_.Run();
}

void TestMenuControllerDelegate::SiblingMenuCreated(MenuItemView* menu) {}

class SubmenuViewShown : public SubmenuView {
 public:
  using SubmenuView::SubmenuView;
  ~SubmenuViewShown() override {}
  bool IsShowing() override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(SubmenuViewShown);
};

class TestEventHandler : public ui::EventHandler {
 public:
  TestEventHandler() : outstanding_touches_(0) {}

  void OnTouchEvent(ui::TouchEvent* event) override {
    switch (event->type()) {
      case ui::ET_TOUCH_PRESSED:
        outstanding_touches_++;
        break;
      case ui::ET_TOUCH_RELEASED:
      case ui::ET_TOUCH_CANCELLED:
        outstanding_touches_--;
        break;
      default:
        break;
    }
  }

  int outstanding_touches() const { return outstanding_touches_; }

 private:
  int outstanding_touches_;
  DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
};

// A test widget that counts gesture events.
class GestureTestWidget : public Widget {
 public:
  GestureTestWidget() {}

  void OnGestureEvent(ui::GestureEvent* event) override { ++gesture_count_; }

  int gesture_count() const { return gesture_count_; }

 private:
  int gesture_count_ = 0;
  DISALLOW_COPY_AND_ASSIGN(GestureTestWidget);
};

#if defined(USE_AURA)
// A DragDropClient which does not trigger a nested run loop. Instead a
// callback is triggered during StartDragAndDrop in order to allow testing.
class TestDragDropClient : public aura::client::DragDropClient {
 public:
  explicit TestDragDropClient(const base::Closure& callback)
      : start_drag_and_drop_callback_(callback), drag_in_progress_(false) {}
  ~TestDragDropClient() override {}

  // aura::client::DragDropClient:
  int StartDragAndDrop(const ui::OSExchangeData& data,
                       aura::Window* root_window,
                       aura::Window* source_window,
                       const gfx::Point& screen_location,
                       int operation,
                       ui::DragDropTypes::DragEventSource source) override;
  void DragCancel() override;
  bool IsDragDropInProgress() override;

  void AddObserver(aura::client::DragDropClientObserver* observer) override {}
  void RemoveObserver(aura::client::DragDropClientObserver* observer) override {
  }

 private:
  base::Closure start_drag_and_drop_callback_;
  bool drag_in_progress_;

  DISALLOW_COPY_AND_ASSIGN(TestDragDropClient);
};

int TestDragDropClient::StartDragAndDrop(
    const ui::OSExchangeData& data,
    aura::Window* root_window,
    aura::Window* source_window,
    const gfx::Point& screen_location,
    int operation,
    ui::DragDropTypes::DragEventSource source) {
  drag_in_progress_ = true;
  start_drag_and_drop_callback_.Run();
  return 0;
}

void TestDragDropClient::DragCancel() {
  drag_in_progress_ = false;
}
bool TestDragDropClient::IsDragDropInProgress() {
  return drag_in_progress_;
}

#endif  // defined(USE_AURA)

// Test implementation of TestViewsDelegate which overrides ReleaseRef in order
// to test destruction order. This simulates Chrome shutting down upon the
// release of the ref. Associated tests should not crash.
class DestructingTestViewsDelegate : public TestViewsDelegate {
 public:
  DestructingTestViewsDelegate() {}
  ~DestructingTestViewsDelegate() override {}

  void set_release_ref_callback(const base::Closure& release_ref_callback) {
    release_ref_callback_ = release_ref_callback;
  }

  // TestViewsDelegate:
  void ReleaseRef() override;

 private:
  base::Closure release_ref_callback_;
  DISALLOW_COPY_AND_ASSIGN(DestructingTestViewsDelegate);
};

void DestructingTestViewsDelegate::ReleaseRef() {
  if (!release_ref_callback_.is_null())
    release_ref_callback_.Run();
}

// View which cancels the menu it belongs to on mouse press.
class CancelMenuOnMousePressView : public View {
 public:
  explicit CancelMenuOnMousePressView(MenuController* controller)
      : controller_(controller) {}

  // View:
  bool OnMousePressed(const ui::MouseEvent& event) override {
    controller_->CancelAll();
    return true;
  }

  // This is needed to prevent the view from being "squashed" to zero height
  // when the menu which owns it is shown. In such state the logic which
  // determines if the menu contains the mouse press location doesn't work.
  gfx::Size CalculatePreferredSize() const override { return size(); }

 private:
  MenuController* controller_;
};

}  // namespace

class TestMenuItemViewShown : public MenuItemView {
 public:
  explicit TestMenuItemViewShown(MenuDelegate* delegate)
      : MenuItemView(delegate) {
    submenu_ = new SubmenuViewShown(this);
  }
  ~TestMenuItemViewShown() override {}

  void SetController(MenuController* controller) { set_controller(controller); }

  void AddEmptyMenusForTest() { AddEmptyMenus(); }

  void SetActualMenuPosition(MenuItemView::MenuPosition position) {
    set_actual_menu_position(position);
  }
  MenuItemView::MenuPosition ActualMenuPosition() {
    return actual_menu_position();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestMenuItemViewShown);
};

class TestMenuItemViewNotShown : public MenuItemView {
 public:
  explicit TestMenuItemViewNotShown(MenuDelegate* delegate)
      : MenuItemView(delegate) {
    submenu_ = new SubmenuView(this);
  }
  ~TestMenuItemViewNotShown() override {}

  void SetController(MenuController* controller) { set_controller(controller); }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestMenuItemViewNotShown);
};

struct MenuBoundsOptions {
 public:
  gfx::Rect anchor_bounds = gfx::Rect(500, 500, 10, 10);
  gfx::Rect monitor_bounds = gfx::Rect(0, 0, 1000, 1000);
  gfx::Size menu_size = gfx::Size(100, 100);
  MenuAnchorPosition menu_anchor = MENU_ANCHOR_TOPLEFT;
  MenuItemView::MenuPosition menu_position = MenuItemView::POSITION_BEST_FIT;
};

class MenuControllerTest : public ViewsTestBase {
 public:
  MenuControllerTest() : menu_controller_(nullptr) {}

  ~MenuControllerTest() override {}

  // ViewsTestBase:
  void SetUp() override {
    std::unique_ptr<DestructingTestViewsDelegate> views_delegate(
        new DestructingTestViewsDelegate());
    test_views_delegate_ = views_delegate.get();
    // ViewsTestBase takes ownership, destroying during Teardown.
    set_views_delegate(std::move(views_delegate));
    ViewsTestBase::SetUp();
    Init();
    ASSERT_TRUE(base::MessageLoopCurrentForUI::IsSet());
  }

  void TearDown() override {
    owner_->CloseNow();
    DestroyMenuController();
    ViewsTestBase::TearDown();
  }

  void ReleaseTouchId(int id) { event_generator_->ReleaseTouchId(id); }

  void PressKey(ui::KeyboardCode key_code) {
    event_generator_->PressKey(key_code, 0);
  }

  void DispatchKey(ui::KeyboardCode key_code) {
    ui::KeyEvent event(ui::EventType::ET_KEY_PRESSED, key_code, 0);
    menu_controller_->OnWillDispatchKeyEvent(&event);
  }

  gfx::Rect CalculateMenuBounds(const MenuBoundsOptions& options) {
    menu_controller_->state_.anchor = options.menu_anchor;
    menu_controller_->state_.initial_bounds = options.anchor_bounds;
    menu_controller_->state_.monitor_bounds = options.monitor_bounds;
    menu_item_->SetActualMenuPosition(options.menu_position);
    menu_item_->GetSubmenu()->GetScrollViewContainer()->SetPreferredSize(
        options.menu_size);
    bool resulting_direction;
    return menu_controller_->CalculateMenuBounds(menu_item_.get(), true,
                                                 &resulting_direction);
  }

#if defined(USE_AURA)
  // Verifies that a non-nested menu fully closes when receiving an escape key.
  void TestAsyncEscapeKey() {
    ui::KeyEvent event(ui::EventType::ET_KEY_PRESSED, ui::VKEY_ESCAPE, 0);
    menu_controller_->OnWillDispatchKeyEvent(&event);
  }

  // Verifies that an open menu receives a cancel event, and closes.
  void TestCancelEvent() {
    EXPECT_EQ(MenuController::EXIT_NONE, menu_controller_->exit_type());
    ui::CancelModeEvent cancel_event;
    event_generator_->Dispatch(&cancel_event);
    EXPECT_EQ(MenuController::EXIT_ALL, menu_controller_->exit_type());
  }
#endif  // defined(USE_AURA)

  // Verifies the state of the |menu_controller_| before destroying it.
  void VerifyDragCompleteThenDestroy() {
    EXPECT_FALSE(menu_controller()->drag_in_progress());
    EXPECT_EQ(MenuController::EXIT_ALL, menu_controller()->exit_type());
    DestroyMenuController();
  }

  // Setups |menu_controller_delegate_| to be destroyed when OnMenuClosed is
  // called.
  void TestDragCompleteThenDestroyOnMenuClosed() {
    menu_controller_delegate_->set_on_menu_closed_callback(
        base::Bind(&MenuControllerTest::VerifyDragCompleteThenDestroy,
                   base::Unretained(this)));
  }

  // Tests destroying the active |menu_controller_| and replacing it with a new
  // active instance.
  void TestMenuControllerReplacementDuringDrag() {
    DestroyMenuController();
    menu_item()->GetSubmenu()->Close();
    const bool for_drop = false;
    menu_controller_ =
        new MenuController(for_drop, menu_controller_delegate_.get());
    menu_controller_->owner_ = owner_.get();
    menu_controller_->showing_ = true;
  }

  // Tests that the menu does not destroy itself when canceled during a drag.
  void TestCancelAllDuringDrag() {
    menu_controller_->CancelAll();
    EXPECT_EQ(0, menu_controller_delegate_->on_menu_closed_called());
  }

  // Tests that destroying the menu during ViewsDelegate::ReleaseRef does not
  // cause a crash.
  void TestDestroyedDuringViewsRelease() {
    // |test_views_delegate_| is owned by views::ViewsTestBase and not deleted
    // until TearDown. MenuControllerTest outlives it.
    test_views_delegate_->set_release_ref_callback(base::Bind(
        &MenuControllerTest::DestroyMenuController, base::Unretained(this)));
    menu_controller_->ExitMenu();
  }

 protected:
  void SetPendingStateItem(MenuItemView* item) {
    menu_controller_->pending_state_.item = item;
    menu_controller_->pending_state_.submenu_open = true;
  }

  void SetState(MenuItemView* item) {
    menu_controller_->state_.item = item;
    menu_controller_->state_.submenu_open = true;
  }

  void ResetSelection() {
    menu_controller_->SetSelection(
        nullptr, MenuController::SELECTION_EXIT |
                     MenuController::SELECTION_UPDATE_IMMEDIATELY);
  }

  void IncrementSelection() {
    menu_controller_->IncrementSelection(
        MenuController::INCREMENT_SELECTION_DOWN);
  }

  void DecrementSelection() {
    menu_controller_->IncrementSelection(
        MenuController::INCREMENT_SELECTION_UP);
  }

  void DestroyMenuControllerOnMenuClosed(TestMenuControllerDelegate* delegate) {
    // Unretained() is safe here as the test should outlive the delegate. If not
    // we want to know.
    delegate->set_on_menu_closed_callback(base::Bind(
        &MenuControllerTest::DestroyMenuController, base::Unretained(this)));
  }

  MenuItemView* FindInitialSelectableMenuItemDown(MenuItemView* parent) {
    return menu_controller_->FindInitialSelectableMenuItem(
        parent, MenuController::INCREMENT_SELECTION_DOWN);
  }

  MenuItemView* FindInitialSelectableMenuItemUp(MenuItemView* parent) {
    return menu_controller_->FindInitialSelectableMenuItem(
        parent, MenuController::INCREMENT_SELECTION_UP);
  }

  MenuItemView* FindNextSelectableMenuItem(MenuItemView* parent,
                                           int index) {
    return menu_controller_->FindNextSelectableMenuItem(
        parent, index, MenuController::INCREMENT_SELECTION_DOWN, false);
  }

  MenuItemView* FindPreviousSelectableMenuItem(MenuItemView* parent,
                                               int index) {
    return menu_controller_->FindNextSelectableMenuItem(
        parent, index, MenuController::INCREMENT_SELECTION_UP, false);
  }

  internal::MenuControllerDelegate* GetCurrentDelegate() {
    return menu_controller_->delegate_;
  }

  bool IsShowing() { return menu_controller_->showing_; }

  MenuHost* GetMenuHost(SubmenuView* submenu) { return submenu->host_; }

  MenuHostRootView* CreateMenuHostRootView(MenuHost* host) {
    return static_cast<MenuHostRootView*>(host->CreateRootView());
  }

  void MenuHostOnDragWillStart(MenuHost* host) { host->OnDragWillStart(); }

  void MenuHostOnDragComplete(MenuHost* host) { host->OnDragComplete(); }

  void SelectByChar(base::char16 character) {
    menu_controller_->SelectByChar(character);
  }

  void SetDropMenuItem(MenuItemView* target,
                       MenuDelegate::DropPosition position) {
    menu_controller_->SetDropMenuItem(target, position);
  }

  void SetIsCombobox(bool is_combobox) {
    menu_controller_->set_is_combobox(is_combobox);
  }

  void SetSelectionOnPointerDown(SubmenuView* source,
                                 const ui::LocatedEvent* event) {
    menu_controller_->SetSelectionOnPointerDown(source, event);
  }

  // Note that coordinates of events passed to MenuController must be in that of
  // the MenuScrollViewContainer.
  void ProcessMousePressed(SubmenuView* source, const ui::MouseEvent& event) {
    menu_controller_->OnMousePressed(source, event);
  }

  void ProcessMouseDragged(SubmenuView* source, const ui::MouseEvent& event) {
    menu_controller_->OnMouseDragged(source, event);
  }

  void ProcessMouseMoved(SubmenuView* source, const ui::MouseEvent& event) {
    menu_controller_->OnMouseMoved(source, event);
  }

  void ProcessMouseReleased(SubmenuView* source, const ui::MouseEvent& event) {
    menu_controller_->OnMouseReleased(source, event);
  }

  void Accept(MenuItemView* item, int event_flags) {
    menu_controller_->Accept(item, event_flags);
    views::test::WaitForMenuClosureAnimation();
  }

  // Causes the |menu_controller_| to begin dragging. Use TestDragDropClient to
  // avoid nesting message loops.
  void StartDrag() {
    const gfx::Point location;
    menu_controller_->state_.item = menu_item()->GetSubmenu()->GetMenuItemAt(0);
    menu_controller_->StartDrag(
        menu_item()->GetSubmenu()->GetMenuItemAt(0)->CreateSubmenu(), location);
  }

  GestureTestWidget* owner() { return owner_.get(); }
  ui::test::EventGenerator* event_generator() { return event_generator_.get(); }
  TestMenuItemViewShown* menu_item() { return menu_item_.get(); }
  TestMenuDelegate* menu_delegate() { return menu_delegate_.get(); }
  TestMenuControllerDelegate* menu_controller_delegate() {
    return menu_controller_delegate_.get();
  }
  MenuController* menu_controller() { return menu_controller_; }
  const MenuItemView* pending_state_item() const {
    return menu_controller_->pending_state_.item;
  }
  MenuController::ExitType menu_exit_type() const {
    return menu_controller_->exit_type_;
  }

  void AddButtonMenuItems() {
    menu_item()->SetBounds(0, 0, 200, 300);
    MenuItemView* item_view =
        menu_item()->AppendMenuItemWithLabel(5, base::ASCIIToUTF16("Five"));
    for (int i = 0; i < 3; ++i) {
      LabelButton* button =
          new LabelButton(nullptr, base::ASCIIToUTF16("Label"));
      // This is an in-menu button. Hence it must be always focusable.
      button->SetFocusBehavior(View::FocusBehavior::ALWAYS);
      item_view->AddChildView(button);
    }
    menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false);
  }

  void DestroyMenuItem() { menu_item_.reset(); }

  Button* GetHotButton() { return menu_controller_->hot_button_; }

  void SetHotTrackedButton(Button* hot_button) {
    menu_controller_->SetHotTrackedButton(hot_button);
  }

  void ExitMenuRun() {
    menu_controller_->SetExitType(MenuController::ExitType::EXIT_OUTERMOST);
    menu_controller_->ExitTopMostMenu();
  }

  void DestroyMenuController() {
    if (!menu_controller_)
      return;

    if (!owner_->IsClosed())
      owner_->RemoveObserver(menu_controller_);

    menu_controller_->showing_ = false;
    menu_controller_->owner_ = nullptr;
    delete menu_controller_;
    menu_controller_ = nullptr;
  }

  int CountOwnerOnGestureEvent() const { return owner_->gesture_count(); }

  bool SelectionWraps() {
    return MenuConfig::instance().arrow_key_selection_wraps;
  }

 private:
  void Init() {
    owner_ = std::make_unique<GestureTestWidget>();
    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
    params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    owner_->Init(params);
    event_generator_ =
        std::make_unique<ui::test::EventGenerator>(GetRootWindow(owner()));
    owner_->Show();

    SetupMenuItem();
    SetupMenuController();
  }

  void SetupMenuItem() {
    menu_delegate_.reset(new TestMenuDelegate);
    menu_item_.reset(new TestMenuItemViewShown(menu_delegate_.get()));
    menu_item_->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One"));
    menu_item_->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two"));
    menu_item_->AppendMenuItemWithLabel(3, base::ASCIIToUTF16("Three"));
    menu_item_->AppendMenuItemWithLabel(4, base::ASCIIToUTF16("Four"));
  }

  void SetupMenuController() {
    menu_controller_delegate_.reset(new TestMenuControllerDelegate);
    const bool for_drop = false;
    menu_controller_ =
        new MenuController(for_drop, menu_controller_delegate_.get());
    menu_controller_->owner_ = owner_.get();
    menu_controller_->showing_ = true;
    menu_controller_->SetSelection(
        menu_item_.get(), MenuController::SELECTION_UPDATE_IMMEDIATELY);
    menu_item_->SetController(menu_controller_);
  }

  // Not owned.
  DestructingTestViewsDelegate* test_views_delegate_;

  std::unique_ptr<GestureTestWidget> owner_;
  std::unique_ptr<ui::test::EventGenerator> event_generator_;
  std::unique_ptr<TestMenuItemViewShown> menu_item_;
  std::unique_ptr<TestMenuControllerDelegate> menu_controller_delegate_;
  std::unique_ptr<TestMenuDelegate> menu_delegate_;
  MenuController* menu_controller_;

  DISALLOW_COPY_AND_ASSIGN(MenuControllerTest);
};

#if defined(USE_X11)
// Tests that an event targeter which blocks events will be honored by the menu
// event dispatcher.
TEST_F(MenuControllerTest, EventTargeter) {
  {
    // With the aura::NullWindowTargeter instantiated and assigned we expect
    // the menu to not handle the key event.
    aura::ScopedWindowTargeter scoped_targeter(
        GetRootWindow(owner()), std::make_unique<aura::NullWindowTargeter>());
    PressKey(ui::VKEY_ESCAPE);
    EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type());
  }
  // Now that the targeter has been destroyed, expect to exit the menu
  // normally when hitting escape.
  TestAsyncEscapeKey();
  EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type());
}

#endif  // defined(USE_X11)

#if defined(USE_X11)
// Tests that touch event ids are released correctly. See crbug.com/439051 for
// details. When the ids aren't managed correctly, we get stuck down touches.
TEST_F(MenuControllerTest, TouchIdsReleasedCorrectly) {
  TestEventHandler test_event_handler;
  GetRootWindow(owner())->AddPreTargetHandler(&test_event_handler);

  std::vector<int> devices;
  devices.push_back(1);
  ui::SetUpTouchDevicesForTest(devices);

  event_generator()->PressTouchId(0);
  event_generator()->PressTouchId(1);
  event_generator()->ReleaseTouchId(0);

  menu_controller()->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                         MENU_ANCHOR_TOPLEFT, false, false);

  MenuControllerTest::ReleaseTouchId(1);
  TestAsyncEscapeKey();

  EXPECT_EQ(MenuController::EXIT_ALL, menu_exit_type());
  EXPECT_EQ(0, test_event_handler.outstanding_touches());

  GetRootWindow(owner())->RemovePreTargetHandler(&test_event_handler);
}
#endif  // defined(USE_X11)

// Tests that initial selected menu items are correct when items are enabled or
// disabled.
TEST_F(MenuControllerTest, InitialSelectedItem) {
  // Leave items "Two", "Three", and "Four" enabled.
  menu_item()->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false);
  // The first selectable item should be item "Two".
  MenuItemView* first_selectable =
      FindInitialSelectableMenuItemDown(menu_item());
  ASSERT_NE(nullptr, first_selectable);
  EXPECT_EQ(2, first_selectable->GetCommand());
  // The last selectable item should be item "Four".
  MenuItemView* last_selectable =
      FindInitialSelectableMenuItemUp(menu_item());
  ASSERT_NE(nullptr, last_selectable);
  EXPECT_EQ(4, last_selectable->GetCommand());

  // Leave items "One" and "Two" enabled.
  menu_item()->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(true);
  menu_item()->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(true);
  menu_item()->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(3)->SetEnabled(false);
  // The first selectable item should be item "One".
  first_selectable = FindInitialSelectableMenuItemDown(menu_item());
  ASSERT_NE(nullptr, first_selectable);
  EXPECT_EQ(1, first_selectable->GetCommand());
  // The last selectable item should be item "Two".
  last_selectable = FindInitialSelectableMenuItemUp(menu_item());
  ASSERT_NE(nullptr, last_selectable);
  EXPECT_EQ(2, last_selectable->GetCommand());

  // Leave only a single item "One" enabled.
  menu_item()->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(true);
  menu_item()->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(3)->SetEnabled(false);
  // The first selectable item should be item "One".
  first_selectable = FindInitialSelectableMenuItemDown(menu_item());
  ASSERT_NE(nullptr, first_selectable);
  EXPECT_EQ(1, first_selectable->GetCommand());
  // The last selectable item should be item "One".
  last_selectable = FindInitialSelectableMenuItemUp(menu_item());
  ASSERT_NE(nullptr, last_selectable);
  EXPECT_EQ(1, last_selectable->GetCommand());

  // Leave only a single item "Three" enabled.
  menu_item()->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(true);
  menu_item()->GetSubmenu()->GetMenuItemAt(3)->SetEnabled(false);
  // The first selectable item should be item "Three".
  first_selectable = FindInitialSelectableMenuItemDown(menu_item());
  ASSERT_NE(nullptr, first_selectable);
  EXPECT_EQ(3, first_selectable->GetCommand());
  // The last selectable item should be item "Three".
  last_selectable = FindInitialSelectableMenuItemUp(menu_item());
  ASSERT_NE(nullptr, last_selectable);
  EXPECT_EQ(3, last_selectable->GetCommand());

  // Leave only a single item ("Two") selected. It should be the first and the
  // last selectable item.
  menu_item()->GetSubmenu()->GetMenuItemAt(0)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(1)->SetEnabled(true);
  menu_item()->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false);
  menu_item()->GetSubmenu()->GetMenuItemAt(3)->SetEnabled(false);
  first_selectable = FindInitialSelectableMenuItemDown(menu_item());
  ASSERT_NE(nullptr, first_selectable);
  EXPECT_EQ(2, first_selectable->GetCommand());
  last_selectable = FindInitialSelectableMenuItemUp(menu_item());
  ASSERT_NE(nullptr, last_selectable);
  EXPECT_EQ(2, last_selectable->GetCommand());

  // There should be no next or previous selectable item since there is only a
  // single enabled item in the menu.
  EXPECT_EQ(nullptr, FindNextSelectableMenuItem(menu_item(), 1));
  EXPECT_EQ(nullptr, FindPreviousSelectableMenuItem(menu_item(), 1));

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

// Tests that opening the menu and pressing 'Home' selects the first menu item.
TEST_F(MenuControllerTest, FirstSelectedItem) {
  SetPendingStateItem(menu_item()->GetSubmenu()->GetMenuItemAt(0));
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Select the first menu item.
  DispatchKey(ui::VKEY_HOME);
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Fake initial root item selection and submenu showing.
  SetPendingStateItem(menu_item());
  EXPECT_EQ(0, pending_state_item()->GetCommand());

  // Select the first menu item.
  DispatchKey(ui::VKEY_HOME);
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Select the last item.
  SetPendingStateItem(menu_item()->GetSubmenu()->GetMenuItemAt(3));
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  // Select the first menu item.
  DispatchKey(ui::VKEY_HOME);
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

// Tests that opening the menu and pressing 'End' selects the last enabled menu
// item.
TEST_F(MenuControllerTest, LastSelectedItem) {
  // Fake initial root item selection and submenu showing.
  SetPendingStateItem(menu_item());
  EXPECT_EQ(0, pending_state_item()->GetCommand());

  // Select the last menu item.
  DispatchKey(ui::VKEY_END);
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  // Select the last item.
  SetPendingStateItem(menu_item()->GetSubmenu()->GetMenuItemAt(3));
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  // Select the last menu item.
  DispatchKey(ui::VKEY_END);
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  // Select the first item.
  SetPendingStateItem(menu_item()->GetSubmenu()->GetMenuItemAt(0));
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Select the last menu item.
  DispatchKey(ui::VKEY_END);
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

// Tests that opening menu and pressing 'Down' and 'Up' iterates over enabled
// items.
TEST_F(MenuControllerTest, NextSelectedItem) {
  // Disabling the item "Three" gets it skipped when using keyboard to navigate.
  menu_item()->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false);

  // Fake initial hot selection.
  SetPendingStateItem(menu_item()->GetSubmenu()->GetMenuItemAt(0));
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Move down in the menu.
  // Select next item.
  IncrementSelection();
  EXPECT_EQ(2, pending_state_item()->GetCommand());

  // Skip disabled item.
  IncrementSelection();
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  if (SelectionWraps()) {
    // Wrap around.
    IncrementSelection();
    EXPECT_EQ(1, pending_state_item()->GetCommand());

    // Move up in the menu.
    // Wrap around.
    DecrementSelection();
    EXPECT_EQ(4, pending_state_item()->GetCommand());
  } else {
    // Don't wrap.
    IncrementSelection();
    EXPECT_EQ(4, pending_state_item()->GetCommand());
  }

  // Skip disabled item.
  DecrementSelection();
  EXPECT_EQ(2, pending_state_item()->GetCommand());

  // Select previous item.
  DecrementSelection();
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

// Tests that opening menu and pressing 'Up' selects the last enabled menu item.
TEST_F(MenuControllerTest, PreviousSelectedItem) {
  // Disabling the item "Four" gets it skipped when using keyboard to navigate.
  menu_item()->GetSubmenu()->GetMenuItemAt(3)->SetEnabled(false);

  // Fake initial root item selection and submenu showing.
  SetPendingStateItem(menu_item());
  EXPECT_EQ(0, pending_state_item()->GetCommand());

  // Move up and select a previous (in our case the last enabled) item.
  DecrementSelection();
  EXPECT_EQ(3, pending_state_item()->GetCommand());

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

// Tests that opening menu and calling SelectByChar works correctly.
TEST_F(MenuControllerTest, SelectByChar) {
  SetIsCombobox(true);

  // Handle null character should do nothing.
  SelectByChar(0);
  EXPECT_EQ(0, pending_state_item()->GetCommand());

  // Handle searching for 'f'; should find "Four".
  SelectByChar('f');
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

TEST_F(MenuControllerTest, SelectChildButtonView) {
  AddButtonMenuItems();
  View* buttons_view = menu_item()->GetSubmenu()->child_at(4);
  ASSERT_NE(nullptr, buttons_view);
  Button* button1 = Button::AsButton(buttons_view->child_at(0));
  ASSERT_NE(nullptr, button1);
  Button* button2 = Button::AsButton(buttons_view->child_at(1));
  ASSERT_NE(nullptr, button2);
  Button* button3 = Button::AsButton(buttons_view->child_at(2));
  ASSERT_NE(nullptr, button2);

  // Handle searching for 'f'; should find "Four".
  SelectByChar('f');
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_FALSE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Move selection to |button1|.
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_TRUE(button1->IsHotTracked());
  EXPECT_FALSE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Move selection to |button2|.
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_TRUE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Move selection to |button3|.
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_FALSE(button2->IsHotTracked());
  EXPECT_TRUE(button3->IsHotTracked());

  // Move a mouse to hot track the |button1|.
  SubmenuView* sub_menu = menu_item()->GetSubmenu();
  gfx::Point location(button1->GetBoundsInScreen().CenterPoint());
  View::ConvertPointFromScreen(sub_menu->GetScrollViewContainer(), &location);
  ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location,
                       ui::EventTimeForNow(), 0, 0);
  ProcessMouseMoved(sub_menu, event);

  // Incrementing selection should move hot tracking to the second button (next
  // after the first button).
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_TRUE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Increment selection twice to wrap around.
  IncrementSelection();
  IncrementSelection();
  if (SelectionWraps())
    EXPECT_EQ(1, pending_state_item()->GetCommand());
  else
    EXPECT_EQ(5, pending_state_item()->GetCommand());

  // Clear references in menu controller to the menu item that is going away.
  ResetSelection();
}

TEST_F(MenuControllerTest, DeleteChildButtonView) {
  AddButtonMenuItems();

  // Handle searching for 'f'; should find "Four".
  SelectByChar('f');
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  View* buttons_view = menu_item()->GetSubmenu()->child_at(4);
  ASSERT_NE(nullptr, buttons_view);
  Button* button1 = Button::AsButton(buttons_view->child_at(0));
  ASSERT_NE(nullptr, button1);
  Button* button2 = Button::AsButton(buttons_view->child_at(1));
  ASSERT_NE(nullptr, button2);
  Button* button3 = Button::AsButton(buttons_view->child_at(2));
  ASSERT_NE(nullptr, button2);
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_FALSE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Increment twice to move selection to |button2|.
  IncrementSelection();
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_TRUE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Delete |button2| while it is hot-tracked.
  // This should update MenuController via ViewHierarchyChanged and reset
  // |hot_button_|.
  delete button2;

  // Incrementing selection should now set hot-tracked item to |button1|.
  // It should not crash.
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_TRUE(button1->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());
}

// Creates a menu with Button child views, simulates running a nested
// menu and tests that existing the nested run restores hot-tracked child view.
TEST_F(MenuControllerTest, ChildButtonHotTrackedWhenNested) {
  AddButtonMenuItems();

  // Handle searching for 'f'; should find "Four".
  SelectByChar('f');
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  View* buttons_view = menu_item()->GetSubmenu()->child_at(4);
  ASSERT_NE(nullptr, buttons_view);
  Button* button1 = Button::AsButton(buttons_view->child_at(0));
  ASSERT_NE(nullptr, button1);
  Button* button2 = Button::AsButton(buttons_view->child_at(1));
  ASSERT_NE(nullptr, button2);
  Button* button3 = Button::AsButton(buttons_view->child_at(2));
  ASSERT_NE(nullptr, button2);
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_FALSE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());

  // Increment twice to move selection to |button2|.
  IncrementSelection();
  IncrementSelection();
  EXPECT_EQ(5, pending_state_item()->GetCommand());
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_TRUE(button2->IsHotTracked());
  EXPECT_FALSE(button3->IsHotTracked());
  EXPECT_EQ(button2, GetHotButton());

  MenuController* controller = menu_controller();
  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);

  // |button2| should stay in hot-tracked state but menu controller should not
  // track it anymore (preventing resetting hot-tracked state when changing
  // selection while a nested run is active).
  EXPECT_TRUE(button2->IsHotTracked());
  EXPECT_EQ(nullptr, GetHotButton());

  // Setting hot-tracked button while nested should get reverted when nested
  // menu run ends.
  SetHotTrackedButton(button1);
  EXPECT_TRUE(button1->IsHotTracked());
  EXPECT_EQ(button1, GetHotButton());

  ExitMenuRun();
  EXPECT_FALSE(button1->IsHotTracked());
  EXPECT_TRUE(button2->IsHotTracked());
  EXPECT_EQ(button2, GetHotButton());
}

// Tests that a menu opened asynchronously, will notify its
// MenuControllerDelegate when Accept is called.
TEST_F(MenuControllerTest, AsynchronousAccept) {
  views::test::DisableMenuClosureAnimations();

  MenuController* controller = menu_controller();
  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);
  TestMenuControllerDelegate* delegate = menu_controller_delegate();
  EXPECT_EQ(0, delegate->on_menu_closed_called());

  MenuItemView* accepted = menu_item()->GetSubmenu()->GetMenuItemAt(0);
  const int kEventFlags = 42;
  Accept(accepted, kEventFlags);

  EXPECT_EQ(1, delegate->on_menu_closed_called());
  EXPECT_EQ(accepted, delegate->on_menu_closed_menu());
  EXPECT_EQ(kEventFlags, delegate->on_menu_closed_mouse_event_flags());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            delegate->on_menu_closed_notify_type());
}

// Tests that a menu opened asynchronously, will notify its
// MenuControllerDelegate when CancelAll is called.
TEST_F(MenuControllerTest, AsynchronousCancelAll) {
  MenuController* controller = menu_controller();

  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);
  TestMenuControllerDelegate* delegate = menu_controller_delegate();
  EXPECT_EQ(0, delegate->on_menu_closed_called());

  controller->CancelAll();
  EXPECT_EQ(1, delegate->on_menu_closed_called());
  EXPECT_EQ(nullptr, delegate->on_menu_closed_menu());
  EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            delegate->on_menu_closed_notify_type());
  EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
}

// Tests that canceling a nested menu restores the previous
// MenuControllerDelegate, and notifies each delegate.
TEST_F(MenuControllerTest, AsynchronousNestedDelegate) {
  MenuController* controller = menu_controller();
  TestMenuControllerDelegate* delegate = menu_controller_delegate();
  std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
      new TestMenuControllerDelegate());

  controller->AddNestedDelegate(nested_delegate.get());
  EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());

  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);

  controller->CancelAll();
  EXPECT_EQ(delegate, GetCurrentDelegate());
  EXPECT_EQ(1, delegate->on_menu_closed_called());
  EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
  EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu());
  EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            nested_delegate->on_menu_closed_notify_type());
  EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
}

// Tests that dropping within an asynchronous menu stops the menu from showing
// and does not notify the controller.
TEST_F(MenuControllerTest, AsynchronousPerformDrop) {
  MenuController* controller = menu_controller();
  SubmenuView* source = menu_item()->GetSubmenu();
  MenuItemView* target = source->GetMenuItemAt(0);

  SetDropMenuItem(target, MenuDelegate::DropPosition::DROP_AFTER);

  ui::OSExchangeData drop_data;
  gfx::PointF location(target->origin());
  ui::DropTargetEvent target_event(drop_data, location, location,
                                   ui::DragDropTypes::DRAG_MOVE);
  controller->OnPerformDrop(source, target_event);

  TestMenuDelegate* menu_delegate =
      static_cast<TestMenuDelegate*>(target->GetDelegate());
  TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
  EXPECT_TRUE(menu_delegate->on_perform_drop_called());
  EXPECT_FALSE(IsShowing());
  EXPECT_EQ(0, controller_delegate->on_menu_closed_called());
}

// Tests that dragging within an asynchronous menu notifies the
// MenuControllerDelegate for shutdown.
TEST_F(MenuControllerTest, AsynchronousDragComplete) {
  MenuController* controller = menu_controller();
  TestDragCompleteThenDestroyOnMenuClosed();

  controller->OnDragWillStart();
  controller->OnDragComplete(true);

  TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
  EXPECT_EQ(1, controller_delegate->on_menu_closed_called());
  EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            controller_delegate->on_menu_closed_notify_type());
}

// Tests that if Cancel is called during a drag, that OnMenuClosed is still
// notified when the drag completes.
TEST_F(MenuControllerTest, AsynchronousCancelDuringDrag) {
  MenuController* controller = menu_controller();
  TestDragCompleteThenDestroyOnMenuClosed();

  controller->OnDragWillStart();
  controller->CancelAll();
  controller->OnDragComplete(true);

  TestMenuControllerDelegate* controller_delegate = menu_controller_delegate();
  EXPECT_EQ(1, controller_delegate->on_menu_closed_called());
  EXPECT_EQ(nullptr, controller_delegate->on_menu_closed_menu());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            controller_delegate->on_menu_closed_notify_type());
}

// Tests that if a menu is destroyed while drag operations are occurring, that
// the MenuHost does not crash as the drag completes.
TEST_F(MenuControllerTest, AsynchronousDragHostDeleted) {
  SubmenuView* submenu = menu_item()->GetSubmenu();
  submenu->ShowAt(owner(), menu_item()->bounds(), false);
  MenuHost* host = GetMenuHost(submenu);
  MenuHostOnDragWillStart(host);
  submenu->Close();
  DestroyMenuItem();
  MenuHostOnDragComplete(host);
}

// Widget destruction and cleanup occurs on the MessageLoop after the
// MenuController has been destroyed. A MenuHostRootView should not attempt to
// access a destroyed MenuController. This test should not cause a crash.
TEST_F(MenuControllerTest, HostReceivesInputBeforeDestruction) {
  SubmenuView* submenu = menu_item()->GetSubmenu();
  submenu->ShowAt(owner(), menu_item()->bounds(), false);
  gfx::Point location(submenu->bounds().bottom_right());
  location.Offset(1, 1);

  MenuHost* host = GetMenuHost(submenu);
  // Normally created as the full Widget is brought up. Explicitly created here
  // for testing.
  std::unique_ptr<MenuHostRootView> root_view(CreateMenuHostRootView(host));
  DestroyMenuController();

  ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location,
                       ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);

  // This should not attempt to access the destroyed MenuController and should
  // not crash.
  root_view->OnMouseMoved(event);
}

// Tests that an asynchronous menu nested within an asynchronous menu closes
// both menus, and notifies both delegates.
TEST_F(MenuControllerTest, DoubleAsynchronousNested) {
  MenuController* controller = menu_controller();
  TestMenuControllerDelegate* delegate = menu_controller_delegate();
  std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
      new TestMenuControllerDelegate());

  // Nested run
  controller->AddNestedDelegate(nested_delegate.get());
  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);

  controller->CancelAll();
  EXPECT_EQ(1, delegate->on_menu_closed_called());
  EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
}

// Tests that setting send_gesture_events_to_owner flag forwards gesture events
// to owner and the forwarding stops when the current gesture sequence ends.
TEST_F(MenuControllerTest, PreserveGestureForOwner) {
  MenuController* controller = menu_controller();
  MenuItemView* item = menu_item();
  controller->Run(owner(), nullptr, item, gfx::Rect(),
                  MENU_ANCHOR_FIXED_BOTTOMCENTER, false, false);
  SubmenuView* sub_menu = item->GetSubmenu();
  sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true);

  gfx::Point location(sub_menu->bounds().bottom_left().x(),
                      sub_menu->bounds().bottom_left().y() + 10);
  ui::GestureEvent event(location.x(), location.y(), 0, ui::EventTimeForNow(),
                         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN));

  // Gesture events should not be forwarded if the flag is not set.
  EXPECT_EQ(CountOwnerOnGestureEvent(), 0);
  EXPECT_FALSE(controller->send_gesture_events_to_owner());
  controller->OnGestureEvent(sub_menu, &event);
  EXPECT_EQ(CountOwnerOnGestureEvent(), 0);

  // The menu's owner should receive gestures triggered outside the menu.
  controller->set_send_gesture_events_to_owner(true);
  controller->OnGestureEvent(sub_menu, &event);
  EXPECT_EQ(CountOwnerOnGestureEvent(), 1);

  ui::GestureEvent event2(location.x(), location.y(), 0, ui::EventTimeForNow(),
                          ui::GestureEventDetails(ui::ET_GESTURE_END));

  controller->OnGestureEvent(sub_menu, &event2);
  EXPECT_EQ(CountOwnerOnGestureEvent(), 2);

  // ET_GESTURE_END resets the |send_gesture_events_to_owner_| flag, so further
  // gesture events should not be sent to the owner.
  controller->OnGestureEvent(sub_menu, &event2);
  EXPECT_EQ(CountOwnerOnGestureEvent(), 2);
}

// Tests that touch outside menu does not closes the menu when forwarding
// gesture events to owner.
TEST_F(MenuControllerTest, NoTouchCloseWhenSendingGesturesToOwner) {
  views::test::DisableMenuClosureAnimations();
  MenuController* controller = menu_controller();

  // Owner wants the gesture events.
  controller->set_send_gesture_events_to_owner(true);

  // Show a sub menu and touch outside of it.
  MenuItemView* item = menu_item();
  SubmenuView* sub_menu = item->GetSubmenu();
  sub_menu->ShowAt(owner(), item->bounds(), false);
  gfx::Point location(sub_menu->bounds().bottom_right());
  location.Offset(1, 1);
  ui::TouchEvent touch_event(
      ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  controller->OnTouchEvent(sub_menu, &touch_event);

  // Menu should still be visible.
  EXPECT_TRUE(IsShowing());

  // The current gesture sequence ends.
  ui::GestureEvent gesture_end_event(
      location.x(), location.y(), 0, ui::EventTimeForNow(),
      ui::GestureEventDetails(ui::ET_GESTURE_END));
  controller->OnGestureEvent(sub_menu, &gesture_end_event);

  // Touch outside again and menu should be closed.
  controller->OnTouchEvent(sub_menu, &touch_event);
  views::test::WaitForMenuClosureAnimation();
  EXPECT_FALSE(IsShowing());
  EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
}

// Tests that a nested menu does not crash when trying to repost events that
// occur outside of the bounds of the menu. Instead a proper shutdown should
// occur.
TEST_F(MenuControllerTest, AsynchronousRepostEvent) {
  views::test::DisableMenuClosureAnimations();
  MenuController* controller = menu_controller();
  TestMenuControllerDelegate* delegate = menu_controller_delegate();
  std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
      new TestMenuControllerDelegate());

  controller->AddNestedDelegate(nested_delegate.get());
  EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());

  MenuItemView* item = menu_item();
  controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
                  false, false);

  // Show a sub menu to target with a pointer selection. However have the event
  // occur outside of the bounds of the entire menu.
  SubmenuView* sub_menu = item->GetSubmenu();
  sub_menu->ShowAt(owner(), item->bounds(), false);
  gfx::Point location(sub_menu->bounds().bottom_right());
  location.Offset(1, 1);
  ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location,
                       ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);

  // When attempting to select outside of all menus this should lead to a
  // shutdown. This should not crash while attempting to repost the event.
  SetSelectionOnPointerDown(sub_menu, &event);
  views::test::WaitForMenuClosureAnimation();

  EXPECT_EQ(delegate, GetCurrentDelegate());
  EXPECT_EQ(1, delegate->on_menu_closed_called());
  EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
  EXPECT_EQ(nullptr, nested_delegate->on_menu_closed_menu());
  EXPECT_EQ(0, nested_delegate->on_menu_closed_mouse_event_flags());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            nested_delegate->on_menu_closed_notify_type());
  EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
}

// Tests that an asynchronous menu reposts touch events that occur outside of
// the bounds of the menu, and that the menu closes.
TEST_F(MenuControllerTest, AsynchronousTouchEventRepostEvent) {
  views::test::DisableMenuClosureAnimations();
  MenuController* controller = menu_controller();
  TestMenuControllerDelegate* delegate = menu_controller_delegate();

  // Show a sub menu to target with a touch event. However have the event occur
  // outside of the bounds of the entire menu.
  MenuItemView* item = menu_item();
  SubmenuView* sub_menu = item->GetSubmenu();
  sub_menu->ShowAt(owner(), item->bounds(), false);
  gfx::Point location(sub_menu->bounds().bottom_right());
  location.Offset(1, 1);
  ui::TouchEvent event(
      ui::ET_TOUCH_PRESSED, location, ui::EventTimeForNow(),
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
  controller->OnTouchEvent(sub_menu, &event);
  views::test::WaitForMenuClosureAnimation();

  EXPECT_FALSE(IsShowing());
  EXPECT_EQ(1, delegate->on_menu_closed_called());
  EXPECT_EQ(nullptr, delegate->on_menu_closed_menu());
  EXPECT_EQ(0, delegate->on_menu_closed_mouse_event_flags());
  EXPECT_EQ(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
            delegate->on_menu_closed_notify_type());
  EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
}

// Tests that having the MenuController deleted during RepostEvent does not
// cause a crash. ASAN bots should not detect use-after-free in MenuController.
TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) {
  views::test::DisableMenuClosureAnimations();
  MenuController* controller = menu_controller();
  std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
      new TestMenuControllerDelegate());

  controller->AddNestedDelegate(nested_delegate.get());
  EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());

  MenuItemView* item = menu_item();
  controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
                  false, false);

  // Show a sub menu to target with a pointer selection. However have the event
  // occur outside of the bounds of the entire menu.
  SubmenuView* sub_menu = item->GetSubmenu();
  sub_menu->ShowAt(owner(), item->bounds(), true);
  gfx::Point location(sub_menu->bounds().bottom_right());
  location.Offset(1, 1);
  ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location,
                       ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);

  // This will lead to MenuController being deleted during the event repost.
  // The remainder of this test, and TearDown should not crash.
  DestroyMenuControllerOnMenuClosed(nested_delegate.get());
  // When attempting to select outside of all menus this should lead to a
  // shutdown. This should not crash while attempting to repost the event.
  SetSelectionOnPointerDown(sub_menu, &event);
  views::test::WaitForMenuClosureAnimation();

  // Close to remove observers before test TearDown
  sub_menu->Close();
  EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
}

// Tests that having the MenuController deleted during OnGestureEvent does not
// cause a crash. ASAN bots should not detect use-after-free in MenuController.
TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) {
  views::test::DisableMenuClosureAnimations();
  MenuController* controller = menu_controller();
  std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
      new TestMenuControllerDelegate());

  controller->AddNestedDelegate(nested_delegate.get());
  EXPECT_EQ(nested_delegate.get(), GetCurrentDelegate());

  MenuItemView* item = menu_item();
  controller->Run(owner(), nullptr, item, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
                  false, false);

  // Show a sub menu to target with a tap event.
  SubmenuView* sub_menu = item->GetSubmenu();
  sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), true);

  gfx::Point location(sub_menu->bounds().CenterPoint());
  ui::GestureEvent event(location.x(), location.y(), 0, ui::EventTimeForNow(),
                         ui::GestureEventDetails(ui::ET_GESTURE_TAP));

  // This will lead to MenuController being deleted during the processing of the
  // gesture event. The remainder of this test, and TearDown should not crash.
  DestroyMenuControllerOnMenuClosed(nested_delegate.get());
  controller->OnGestureEvent(sub_menu, &event);
  views::test::WaitForMenuClosureAnimation();

  // Close to remove observers before test TearDown
  sub_menu->Close();
  EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
}

TEST_F(MenuControllerTest, ArrowKeysAtEnds) {
  menu_item()->GetSubmenu()->GetMenuItemAt(2)->SetEnabled(false);

  SetPendingStateItem(menu_item()->GetSubmenu()->GetMenuItemAt(0));
  EXPECT_EQ(1, pending_state_item()->GetCommand());

  if (SelectionWraps()) {
    DispatchKey(ui::VKEY_UP);
    EXPECT_EQ(4, pending_state_item()->GetCommand());

    DispatchKey(ui::VKEY_DOWN);
    EXPECT_EQ(1, pending_state_item()->GetCommand());
  } else {
    DispatchKey(ui::VKEY_UP);
    EXPECT_EQ(1, pending_state_item()->GetCommand());
  }

  DispatchKey(ui::VKEY_DOWN);
  EXPECT_EQ(2, pending_state_item()->GetCommand());

  DispatchKey(ui::VKEY_DOWN);
  EXPECT_EQ(4, pending_state_item()->GetCommand());

  DispatchKey(ui::VKEY_DOWN);
  if (SelectionWraps())
    EXPECT_EQ(1, pending_state_item()->GetCommand());
  else
    EXPECT_EQ(4, pending_state_item()->GetCommand());
}

// Test that the menu is properly placed where it best fits.
TEST_F(MenuControllerTest, CalculateMenuBoundsBestFitTest) {
  MenuBoundsOptions options;
  gfx::Rect expected;

  // Fits in all locations -> placed below.
  options.anchor_bounds =
      gfx::Rect(options.menu_size.width(), options.menu_size.height(), 0, 0);
  options.monitor_bounds =
      gfx::Rect(0, 0, options.anchor_bounds.right() + options.menu_size.width(),
                options.anchor_bounds.bottom() + options.menu_size.height());
  expected =
      gfx::Rect(options.anchor_bounds.x(), options.anchor_bounds.bottom(),
                options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Fits above and to both sides -> placed above.
  options.anchor_bounds =
      gfx::Rect(options.menu_size.width(), options.menu_size.height(), 0, 0);
  options.monitor_bounds =
      gfx::Rect(0, 0, options.anchor_bounds.right() + options.menu_size.width(),
                options.anchor_bounds.bottom());
  expected = gfx::Rect(options.anchor_bounds.x(),
                       options.anchor_bounds.y() - options.menu_size.height(),
                       options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Fits on both sides, prefer right -> placed right.
  options.anchor_bounds = gfx::Rect(options.menu_size.width(),
                                    options.menu_size.height() / 2, 0, 0);
  options.monitor_bounds =
      gfx::Rect(0, 0, options.anchor_bounds.right() + options.menu_size.width(),
                options.menu_size.height());
  expected =
      gfx::Rect(options.anchor_bounds.right(),
                options.monitor_bounds.bottom() - options.menu_size.height(),
                options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Fits only on left -> placed left.
  options.anchor_bounds = gfx::Rect(options.menu_size.width(),
                                    options.menu_size.height() / 2, 0, 0);
  options.monitor_bounds = gfx::Rect(0, 0, options.anchor_bounds.right(),
                                     options.menu_size.height());
  expected =
      gfx::Rect(options.anchor_bounds.x() - options.menu_size.width(),
                options.monitor_bounds.bottom() - options.menu_size.height(),
                options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Fits on both sides, prefer left -> placed left.
  options.menu_anchor = MENU_ANCHOR_TOPRIGHT;
  options.anchor_bounds = gfx::Rect(options.menu_size.width(),
                                    options.menu_size.height() / 2, 0, 0);
  options.monitor_bounds =
      gfx::Rect(0, 0, options.anchor_bounds.right() + options.menu_size.width(),
                options.menu_size.height());
  expected =
      gfx::Rect(options.anchor_bounds.x() - options.menu_size.width(),
                options.monitor_bounds.bottom() - options.menu_size.height(),
                options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Fits only on right -> placed right.
  options.anchor_bounds = gfx::Rect(0, options.menu_size.height() / 2, 0, 0);
  options.monitor_bounds =
      gfx::Rect(0, 0, options.anchor_bounds.right() + options.menu_size.width(),
                options.menu_size.height());
  expected =
      gfx::Rect(options.anchor_bounds.right(),
                options.monitor_bounds.bottom() - options.menu_size.height(),
                options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));
}

// Tests that the menu is properly placed according to its anchor.
TEST_F(MenuControllerTest, CalculateMenuBoundsAnchorTest) {
  MenuBoundsOptions options;
  gfx::Rect expected;

  options.menu_anchor = MENU_ANCHOR_TOPLEFT;
  expected =
      gfx::Rect(options.anchor_bounds.x(), options.anchor_bounds.bottom(),
                options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  options.menu_anchor = MENU_ANCHOR_TOPRIGHT;
  expected =
      gfx::Rect(options.anchor_bounds.right() - options.menu_size.width(),
                options.anchor_bounds.bottom(), options.menu_size.width(),
                options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Menu will be placed above or below with an offset.
  options.menu_anchor = MENU_ANCHOR_BOTTOMCENTER;
  const int kTouchYPadding = 15;

  // Menu fits above -> placed above.
  expected = gfx::Rect(
      options.anchor_bounds.x() +
          (options.anchor_bounds.width() - options.menu_size.width()) / 2,
      options.anchor_bounds.y() - options.menu_size.height() - kTouchYPadding,
      options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Menu does not fit above -> placed below.
  options.anchor_bounds = gfx::Rect(options.menu_size.height() / 2,
                                    options.menu_size.width(), 0, 0);
  expected = gfx::Rect(
      options.anchor_bounds.x() +
          (options.anchor_bounds.width() - options.menu_size.width()) / 2,
      options.anchor_bounds.y() + kTouchYPadding, options.menu_size.width(),
      options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Assumes anchor bounds is at the bottom of screen.
  options.menu_anchor = MENU_ANCHOR_FIXED_BOTTOMCENTER;
  options.anchor_bounds =
      gfx::Rect(options.menu_size.width(), options.menu_size.height(), 0, 0);
  options.monitor_bounds = gfx::Rect(0, 0, options.menu_size.width() * 2,
                                     options.menu_size.height());
  expected = gfx::Rect(
      options.anchor_bounds.x() +
          (options.anchor_bounds.width() - options.menu_size.width()) / 2,
      options.anchor_bounds.y() - options.menu_size.height(),
      options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  // Assumes anchor bounds is on left/right edge of screen.
  options.menu_anchor = MENU_ANCHOR_FIXED_SIDECENTER;
  options.monitor_bounds = gfx::Rect(0, 0, options.menu_size.width(),
                                     options.menu_size.height() * 2);
  options.anchor_bounds =
      gfx::Rect(options.monitor_bounds.x(), options.menu_size.height(), 0, 0);
  expected = gfx::Rect(
      options.anchor_bounds.x(),
      options.anchor_bounds.y() +
          (options.anchor_bounds.height() - options.menu_size.height()) / 2,
      options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  options.anchor_bounds = gfx::Rect(options.monitor_bounds.right(),
                                    options.menu_size.height(), 0, 0);
  expected = gfx::Rect(
      options.anchor_bounds.right() - options.menu_size.width(),
      options.anchor_bounds.y() +
          (options.anchor_bounds.height() - options.menu_size.height()) / 2,
      options.menu_size.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));
}

TEST_F(MenuControllerTest, CalculateMenuBoundsMonitorFitTest) {
  MenuBoundsOptions options;
  gfx::Rect expected;
  options.monitor_bounds = gfx::Rect(0, 0, 100, 100);
  options.anchor_bounds = gfx::Rect();

  options.menu_size = gfx::Size(options.monitor_bounds.width() / 2,
                                options.monitor_bounds.height() * 2);
  expected =
      gfx::Rect(options.anchor_bounds.x(), options.anchor_bounds.bottom(),
                options.menu_size.width(), options.monitor_bounds.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  options.menu_size = gfx::Size(options.monitor_bounds.width() * 2,
                                options.monitor_bounds.height() / 2);
  expected =
      gfx::Rect(options.anchor_bounds.x(), options.anchor_bounds.bottom(),
                options.monitor_bounds.width(), options.menu_size.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));

  options.menu_size = gfx::Size(options.monitor_bounds.width() * 2,
                                options.monitor_bounds.height() * 2);
  expected = gfx::Rect(
      options.anchor_bounds.x(), options.anchor_bounds.bottom(),
      options.monitor_bounds.width(), options.monitor_bounds.height());
  EXPECT_EQ(expected, CalculateMenuBounds(options));
}

// Test that a menu that was originally drawn below the anchor does not get
// squished or move above the anchor when it grows vertically and horizontally
// beyond the monitor bounds.
TEST_F(MenuControllerTest, GrowingMenuMovesLaterallyNotVertically) {
  MenuBoundsOptions options;
  options.monitor_bounds = gfx::Rect(0, 0, 100, 100);
  // The anchor should be near the bottom right side of the screen.
  options.anchor_bounds = gfx::Rect(80, 70, 15, 10);
  // The menu should fit the available space, below the anchor.
  options.menu_size = gfx::Size(20, 20);

  // Ensure the menu is initially drawn below the bounds, and the MenuPosition
  // is set to POSITION_BELOW_BOUNDS;
  const gfx::Rect first_drawn_expected(80, 80, 20, 20);
  EXPECT_EQ(first_drawn_expected, CalculateMenuBounds(options));
  EXPECT_EQ(MenuItemView::MenuPosition::POSITION_BELOW_BOUNDS,
            menu_item()->ActualMenuPosition());

  options.menu_position = MenuItemView::MenuPosition::POSITION_BELOW_BOUNDS;

  // The menu bounds are larger than the remaining space on the monitor. This
  // simulates the case where the menu has been grown vertically and
  // horizontally to where it would no longer fit on the screen.
  options.menu_size = gfx::Size(50, 50);

  // The menu bounds should move left to show the wider menu, and grow to fill
  // the remaining vertical space without moving upwards.
  const gfx::Rect final_expected(50, 80, 50, 20);
  EXPECT_EQ(final_expected, CalculateMenuBounds(options));
}

#if defined(USE_AURA)
// This tests that mouse moved events from the initial position of the mouse
// when the menu was shown don't select the menu item at the mouse position.
TEST_F(MenuControllerTest, MouseAtMenuItemOnShow) {
  // aura::Window::MoveCursorTo check fails in Mus due to null
  // window_manager_client_.
  if (IsMus())
    return;

  // Most tests create an already shown menu but this test needs one that's
  // not shown, so it can show it. The mouse position is remembered when
  // the menu is shown.
  std::unique_ptr<TestMenuItemViewNotShown> menu_item(
      new TestMenuItemViewNotShown(menu_delegate()));
  MenuItemView* first_item =
      menu_item->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One"));
  menu_item->AppendMenuItemWithLabel(2, base::ASCIIToUTF16("Two"));
  menu_item->SetController(menu_controller());

  // Move the mouse to where the first menu item will be shown,
  // and show the menu.
  gfx::Size item_size = first_item->CalculatePreferredSize();
  gfx::Point location(item_size.width() / 2, item_size.height() / 2);
  GetRootWindow(owner())->MoveCursorTo(location);
  menu_controller()->Run(owner(), nullptr, menu_item.get(), gfx::Rect(),
                         MENU_ANCHOR_TOPLEFT, false, false);

  EXPECT_EQ(0, pending_state_item()->GetCommand());

  // Synthesize an event at the mouse position when the menu was opened.
  // It should be ignored, and selected item shouldn't change.
  SubmenuView* sub_menu = menu_item->GetSubmenu();
  View::ConvertPointFromScreen(sub_menu->GetScrollViewContainer(), &location);
  ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location,
                       ui::EventTimeForNow(), 0, 0);
  ProcessMouseMoved(sub_menu, event);
  EXPECT_EQ(0, pending_state_item()->GetCommand());
  // Synthesize an event at a slightly different mouse position. It
  // should cause the item under the cursor to be selected.
  location.Offset(0, 1);
  ui::MouseEvent second_event(ui::ET_MOUSE_MOVED, location, location,
                              ui::EventTimeForNow(), 0, 0);
  ProcessMouseMoved(sub_menu, second_event);
  EXPECT_EQ(1, pending_state_item()->GetCommand());
}

// Tests that when an asynchronous menu receives a cancel event, that it closes.
TEST_F(MenuControllerTest, AsynchronousCancelEvent) {
  ExitMenuRun();
  MenuController* controller = menu_controller();
  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);
  EXPECT_EQ(MenuController::EXIT_NONE, controller->exit_type());
  ui::CancelModeEvent cancel_event;
  event_generator()->Dispatch(&cancel_event);
  EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type());
}

// Tests that menus without parent widgets do not crash in MenuPreTargetHandler.
// This is generally true, except on Chrome OS running with the window service.
// In that case, a DCHECK fires to ensure menus can consume parents' key events.
TEST_F(MenuControllerTest, RunWithoutWidgetDoesntCrash) {
#if defined(OS_CHROMEOS)
  if (features::IsUsingWindowService())
    return;
#endif  // OS_CHROMEOS

  ExitMenuRun();
  MenuController* controller = menu_controller();
  controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);
}

// Tests that if a MenuController is destroying during drag/drop, and another
// MenuController becomes active, that the exiting of drag does not cause a
// crash.
TEST_F(MenuControllerTest, MenuControllerReplacedDuringDrag) {
  // Build the menu so that the appropriate root window is available to set the
  // drag drop client on.
  AddButtonMenuItems();
  TestDragDropClient drag_drop_client(
      base::Bind(&MenuControllerTest::TestMenuControllerReplacementDuringDrag,
                 base::Unretained(this)));
  aura::client::SetDragDropClient(
      GetRootWindow(menu_item()->GetSubmenu()->GetWidget()), &drag_drop_client);
  StartDrag();
}

// Tests that if a CancelAll is called during drag-and-drop that it does not
// destroy the MenuController. On Windows and Linux this destruction also
// destroys the Widget used for drag-and-drop, thereby ending the drag.
TEST_F(MenuControllerTest, CancelAllDuringDrag) {
  // Build the menu so that the appropriate root window is available to set the
  // drag drop client on.
  AddButtonMenuItems();
  TestDragDropClient drag_drop_client(base::Bind(
      &MenuControllerTest::TestCancelAllDuringDrag, base::Unretained(this)));
  aura::client::SetDragDropClient(
      GetRootWindow(menu_item()->GetSubmenu()->GetWidget()), &drag_drop_client);
  StartDrag();
}

// Tests that when releasing the ref on ViewsDelegate and MenuController is
// deleted, that shutdown occurs without crashing.
TEST_F(MenuControllerTest, DestroyedDuringViewsRelease) {
  ExitMenuRun();
  MenuController* controller = menu_controller();
  controller->Run(owner(), nullptr, menu_item(), gfx::Rect(),
                  MENU_ANCHOR_TOPLEFT, false, false);
  TestDestroyedDuringViewsRelease();
}

// Tests that when a context menu is opened above an empty menu item, and a
// right-click occurs over the empty item, that the bottom menu is not hidden,
// that a request to relaunch the context menu is received, and that
// subsequently pressing ESC does not crash the browser.
TEST_F(MenuControllerTest, RepostEventToEmptyMenuItem) {
  // Setup a submenu. Additionally hook up appropriate Widget and View
  // containers, with bounds, so that hit testing works.
  MenuController* controller = menu_controller();
  MenuItemView* base_menu = menu_item();
  base_menu->SetBounds(0, 0, 200, 200);
  SubmenuView* base_submenu = base_menu->GetSubmenu();
  base_submenu->SetBounds(0, 0, 200, 200);
  base_submenu->ShowAt(owner(), gfx::Rect(0, 0, 200, 200), false);
  GetMenuHost(base_submenu)
      ->SetContentsView(base_submenu->GetScrollViewContainer());

  // Build the submenu to have an empty menu item. Additionally hook up
  // appropriate Widget and View containers with bounds, so that hit testing
  // works.
  std::unique_ptr<TestMenuDelegate> sub_menu_item_delegate =
      std::make_unique<TestMenuDelegate>();
  std::unique_ptr<TestMenuItemViewShown> sub_menu_item =
      std::make_unique<TestMenuItemViewShown>(sub_menu_item_delegate.get());
  sub_menu_item->AddEmptyMenusForTest();
  sub_menu_item->SetController(controller);
  sub_menu_item->SetBounds(0, 50, 50, 50);
  base_submenu->AddChildView(sub_menu_item.get());
  SubmenuView* sub_menu_view = sub_menu_item->GetSubmenu();
  sub_menu_view->SetBounds(0, 50, 50, 50);
  sub_menu_view->ShowAt(owner(), gfx::Rect(0, 50, 50, 50), false);
  GetMenuHost(sub_menu_view)
      ->SetContentsView(sub_menu_view->GetScrollViewContainer());

  // Set that the last selection target was the item which launches the submenu,
  // as the empty item can never become a target.
  SetPendingStateItem(sub_menu_item.get());

  // Nest a context menu.
  std::unique_ptr<TestMenuDelegate> nested_menu_delegate_1 =
      std::make_unique<TestMenuDelegate>();
  std::unique_ptr<TestMenuItemViewShown> nested_menu_item_1 =
      std::make_unique<TestMenuItemViewShown>(nested_menu_delegate_1.get());
  nested_menu_item_1->SetBounds(0, 0, 100, 100);
  nested_menu_item_1->SetController(controller);
  std::unique_ptr<TestMenuControllerDelegate> nested_controller_delegate_1 =
      std::make_unique<TestMenuControllerDelegate>();
  controller->AddNestedDelegate(nested_controller_delegate_1.get());
  controller->Run(owner(), nullptr, nested_menu_item_1.get(),
                  gfx::Rect(150, 50, 100, 100), MENU_ANCHOR_TOPLEFT, true,
                  false);

  SubmenuView* nested_menu_submenu = nested_menu_item_1->GetSubmenu();
  nested_menu_submenu->SetBounds(0, 0, 100, 100);
  nested_menu_submenu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), false);
  GetMenuHost(nested_menu_submenu)
      ->SetContentsView(nested_menu_submenu->GetScrollViewContainer());

  // Press down outside of the context menu, and within the empty menu item.
  // This should close the first context menu.
  gfx::Point press_location(sub_menu_view->bounds().CenterPoint());
  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, press_location,
                             press_location, ui::EventTimeForNow(),
                             ui::EF_RIGHT_MOUSE_BUTTON, 0);
  ProcessMousePressed(nested_menu_submenu, press_event);
  EXPECT_EQ(nested_controller_delegate_1->on_menu_closed_called(), 1);
  EXPECT_EQ(menu_controller_delegate(), GetCurrentDelegate());

  // While the current state is the menu item which launched the sub menu, cause
  // a drag in the empty menu item. This should not hide the menu.
  SetState(sub_menu_item.get());
  press_location.Offset(-5, 0);
  ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, press_location,
                            press_location, ui::EventTimeForNow(),
                            ui::EF_RIGHT_MOUSE_BUTTON, 0);
  ProcessMouseDragged(sub_menu_view, drag_event);
  EXPECT_EQ(menu_delegate()->will_hide_menu_count(), 0);

  // Release the mouse in the empty menu item, triggering a context menu
  // request.
  ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, press_location,
                               press_location, ui::EventTimeForNow(),
                               ui::EF_RIGHT_MOUSE_BUTTON, 0);
  ProcessMouseReleased(sub_menu_view, release_event);
  EXPECT_EQ(sub_menu_item_delegate->show_context_menu_count(), 1);
  EXPECT_EQ(sub_menu_item_delegate->show_context_menu_source(),
            sub_menu_item.get());

  // Nest a context menu.
  std::unique_ptr<TestMenuDelegate> nested_menu_delegate_2 =
      std::make_unique<TestMenuDelegate>();
  std::unique_ptr<TestMenuItemViewShown> nested_menu_item_2 =
      std::make_unique<TestMenuItemViewShown>(nested_menu_delegate_2.get());
  nested_menu_item_2->SetBounds(0, 0, 100, 100);
  nested_menu_item_2->SetController(controller);

  std::unique_ptr<TestMenuControllerDelegate> nested_controller_delegate_2 =
      std::make_unique<TestMenuControllerDelegate>();
  controller->AddNestedDelegate(nested_controller_delegate_2.get());
  controller->Run(owner(), nullptr, nested_menu_item_2.get(),
                  gfx::Rect(150, 50, 100, 100), MENU_ANCHOR_TOPLEFT, true,
                  false);

  // The escape key should only close the nested menu. SelectByChar should not
  // crash.
  TestAsyncEscapeKey();
  EXPECT_EQ(nested_controller_delegate_2->on_menu_closed_called(), 1);
  EXPECT_EQ(menu_controller_delegate(), GetCurrentDelegate());
}

// Drag the mouse from an external view into a menu
// When the mouse leaves the menu while still in the process of dragging
// the menu item view highlight should turn off
TEST_F(MenuControllerTest, DragFromViewIntoMenuAndExit) {
  SubmenuView* sub_menu = menu_item()->GetSubmenu();
  MenuItemView* first_item = sub_menu->GetMenuItemAt(0);

  std::unique_ptr<View> drag_view = std::make_unique<View>();
  drag_view->SetBoundsRect(gfx::Rect(0, 500, 100, 100));
  sub_menu->ShowAt(owner(), gfx::Rect(0, 0, 100, 100), false);
  gfx::Point press_location(drag_view->bounds().CenterPoint());
  gfx::Point drag_location(first_item->bounds().CenterPoint());
  gfx::Point release_location(200, 50);

  // Begin drag on an external view
  ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, press_location,
                             press_location, ui::EventTimeForNow(),
                             ui::EF_LEFT_MOUSE_BUTTON, 0);
  drag_view->OnMousePressed(press_event);

  // Drag into a menu item
  ui::MouseEvent drag_event_enter(ui::ET_MOUSE_DRAGGED, drag_location,
                                  drag_location, ui::EventTimeForNow(),
                                  ui::EF_LEFT_MOUSE_BUTTON, 0);
  ProcessMouseDragged(sub_menu, drag_event_enter);
  EXPECT_TRUE(first_item->IsSelected());

  // Drag out of the menu item
  ui::MouseEvent drag_event_exit(ui::ET_MOUSE_DRAGGED, release_location,
                                 release_location, ui::EventTimeForNow(),
                                 ui::EF_LEFT_MOUSE_BUTTON, 0);
  ProcessMouseDragged(sub_menu, drag_event_exit);
  EXPECT_FALSE(first_item->IsSelected());

  // Complete drag with release
  ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED, release_location,
                               release_location, ui::EventTimeForNow(),
                               ui::EF_LEFT_MOUSE_BUTTON, 0);
  ProcessMouseReleased(sub_menu, release_event);
}

#endif  // defined(USE_AURA)

// Tests that having the MenuController deleted during OnMousePressed does not
// cause a crash. ASAN bots should not detect use-after-free in MenuController.
TEST_F(MenuControllerTest, NoUseAfterFreeWhenMenuCanceledOnMousePress) {
  MenuController* controller = menu_controller();
  DestroyMenuControllerOnMenuClosed(menu_controller_delegate());

  // Creating own MenuItem for a minimal test environment.
  auto item = std::make_unique<TestMenuItemViewNotShown>(menu_delegate());
  item->SetController(controller);
  item->SetBounds(0, 0, 50, 50);

  SubmenuView* sub_menu = item->CreateSubmenu();
  auto* canceling_view = new CancelMenuOnMousePressView(controller);
  sub_menu->AddChildView(canceling_view);
  canceling_view->SetBoundsRect(item->bounds());

  controller->Run(owner(), nullptr, item.get(), item->bounds(),
                  MENU_ANCHOR_TOPLEFT, false, false);
  sub_menu->ShowAt(owner(), item->bounds(), true);

  // Simulate a mouse press in the middle of the |closing_widget|.
  gfx::Point location(canceling_view->bounds().CenterPoint());
  ui::MouseEvent event(ui::ET_MOUSE_PRESSED, location, location,
                       ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
  EXPECT_TRUE(controller->OnMousePressed(sub_menu, event));

  // Close to remove observers before test TearDown.
  sub_menu->Close();
}

}  // namespace test
}  // namespace views
