// Copyright (c) 2012 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/shell.h"

#include <algorithm>
#include <memory>
#include <queue>
#include <vector>

#include "ash/display/mouse_cursor_event_filter.h"
#include "ash/drag_drop/drag_drop_controller.h"
#include "ash/drag_drop/drag_drop_controller_test_api.h"
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/keyboard/ui/keyboard_util.h"
#include "ash/public/cpp/ash_prefs.h"
#include "ash/public/cpp/keyboard/keyboard_switches.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/test/shell_test_api.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller_impl.h"
#include "ash/session/test_session_controller_client.h"
#include "ash/shelf/home_button.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_navigation_widget.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/system/status_area_widget.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/ash_test_helper.h"
#include "ash/test/test_widget_builder.h"
#include "ash/test_shell_delegate.h"
#include "ash/wallpaper/wallpaper_widget_controller.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/account_id/account_id.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/display/scoped_display_for_new_windows.h"
#include "ui/events/test/event_generator.h"
#include "ui/events/test/events_test_utils.h"
#include "ui/events/test/test_event_handler.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/dialog_delegate.h"

using aura::RootWindow;

namespace ash {

namespace {

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

aura::Window* GetAlwaysOnTopContainer() {
  return Shell::GetContainer(Shell::GetPrimaryRootWindow(),
                             kShellWindowId_AlwaysOnTopContainer);
}

// Expect ALL the containers!
void ExpectAllContainers() {
  aura::Window* root_window = Shell::GetPrimaryRootWindow();

  // Validate no duplicate container IDs.
  base::flat_set<int> container_ids;
  std::queue<aura::Window*> window_queue;
  window_queue.push(root_window);
  while (!window_queue.empty()) {
    aura::Window* current_window = window_queue.front();
    window_queue.pop();
    for (aura::Window* child : current_window->children())
      window_queue.push(child);

    const int id = current_window->GetId();

    // Skip windows with no IDs.
    if (id == aura::Window::kInitialId)
      continue;

    EXPECT_TRUE(container_ids.insert(id).second)
        << "Found duplicate ID: " << id
        << " at window: " << current_window->GetName();
  }

  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_WallpaperContainer));

  for (int desk_id : desks_util::GetDesksContainersIds())
    EXPECT_TRUE(Shell::GetContainer(root_window, desk_id));

  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window, kShellWindowId_ShelfContainer));
  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_SystemModalContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window,
                                  kShellWindowId_LockScreenWallpaperContainer));
  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_LockScreenContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window,
                                  kShellWindowId_LockSystemModalContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window, kShellWindowId_MenuContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window,
                                  kShellWindowId_DragImageAndTooltipContainer));
  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_SettingBubbleContainer));
  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_OverlayContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window,
                                  kShellWindowId_ImeWindowParentContainer));
  EXPECT_TRUE(Shell::GetContainer(root_window,
                                  kShellWindowId_VirtualKeyboardContainer));
  EXPECT_TRUE(
      Shell::GetContainer(root_window, kShellWindowId_MouseCursorContainer));

  // Phantom window is not a container.
  EXPECT_EQ(0u, container_ids.count(kShellWindowId_PhantomWindow));
  EXPECT_FALSE(Shell::GetContainer(root_window, kShellWindowId_PhantomWindow));
}

std::unique_ptr<views::WidgetDelegateView> CreateModalWidgetDelegate() {
  auto delegate = std::make_unique<views::WidgetDelegateView>();
  delegate->SetCanResize(true);
  delegate->SetModalType(ui::MODAL_TYPE_SYSTEM);
  delegate->SetOwnedByWidget(true);
  delegate->SetTitle(u"Modal Window");
  return delegate;
}

class SimpleMenuDelegate : public ui::SimpleMenuModel::Delegate {
 public:
  SimpleMenuDelegate() = default;
  ~SimpleMenuDelegate() override = default;

  bool IsCommandIdChecked(int command_id) const override { return false; }

  bool IsCommandIdEnabled(int command_id) const override { return true; }

  void ExecuteCommand(int command_id, int event_flags) override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(SimpleMenuDelegate);
};

}  // namespace

class ShellTest : public AshTestBase {
 public:
  void TestCreateWindow(views::Widget::InitParams::Type type,
                        bool always_on_top,
                        aura::Window* expected_container) {
    TestWidgetBuilder builder;
    if (always_on_top)
      builder.SetZOrderLevel(ui::ZOrderLevel::kFloatingWindow);
    views::Widget* widget =
        builder.SetWidgetType(type).BuildOwnedByNativeWidget();

    EXPECT_TRUE(
        expected_container->Contains(widget->GetNativeWindow()->parent()))
        << "TestCreateWindow: type=" << type
        << ", always_on_top=" << always_on_top;

    widget->Close();
  }

  void LockScreenAndVerifyMenuClosed() {
    // Verify a menu is open before locking.
    views::MenuController* menu_controller =
        views::MenuController::GetActiveInstance();
    DCHECK(menu_controller);
    EXPECT_EQ(views::MenuController::ExitType::kNone,
              menu_controller->exit_type());

    // Create a LockScreen window.
    views::Widget* lock_widget =
        TestWidgetBuilder()
            .SetWidgetType(views::Widget::InitParams::TYPE_WINDOW)
            .SetShow(false)
            .BuildOwnedByNativeWidget();
    Shell::GetContainer(Shell::GetPrimaryRootWindow(),
                        kShellWindowId_LockScreenContainer)
        ->AddChild(lock_widget->GetNativeView());
    lock_widget->Show();

    // Simulate real screen locker to change session state to LOCKED
    // when it is shown.
    GetSessionControllerClient()->LockScreen();

    SessionControllerImpl* controller = Shell::Get()->session_controller();
    EXPECT_TRUE(controller->IsScreenLocked());
    EXPECT_TRUE(lock_widget->GetNativeView()->HasFocus());

    // Verify menu is closed.
    EXPECT_EQ(nullptr, views::MenuController::GetActiveInstance());
    lock_widget->Close();
    GetSessionControllerClient()->UnlockScreen();
  }
};

TEST_F(ShellTest, CreateWindow) {
  // Normal window should be created in default container.
  TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW,
                   false,  // always_on_top
                   GetActiveDeskContainer());
  TestCreateWindow(views::Widget::InitParams::TYPE_POPUP,
                   false,  // always_on_top
                   GetActiveDeskContainer());

  // Always-on-top window and popup are created in always-on-top container.
  TestCreateWindow(views::Widget::InitParams::TYPE_WINDOW,
                   true,  // always_on_top
                   GetAlwaysOnTopContainer());
  TestCreateWindow(views::Widget::InitParams::TYPE_POPUP,
                   true,  // always_on_top
                   GetAlwaysOnTopContainer());
}

// Verifies that a window with a preferred size is created centered on the
// default display for new windows. Mojo apps like shortcut_viewer rely on this
// behavior.
TEST_F(ShellTest, CreateWindowWithPreferredSize) {
  UpdateDisplay("1024x768,800x600");

  aura::Window* secondary_root = Shell::GetAllRootWindows()[1];
  display::ScopedDisplayForNewWindows scoped_display(secondary_root);

  views::Widget::InitParams params;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  // Don't specify bounds, parent or context.
  {
    auto delegate = std::make_unique<views::WidgetDelegateView>();
    delegate->SetPreferredSize(gfx::Size(400, 300));
    params.delegate = delegate.release();
  }
  views::Widget widget;
  params.context = GetContext();
  widget.Init(std::move(params));

  // Widget is centered on secondary display.
  EXPECT_EQ(secondary_root, widget.GetNativeWindow()->GetRootWindow());
  EXPECT_EQ(GetSecondaryDisplay().work_area().CenterPoint(),
            widget.GetRestoredBounds().CenterPoint());
}

TEST_F(ShellTest, ChangeZOrderLevel) {
  // Creates a normal window.
  views::Widget* widget = TestWidgetBuilder().BuildOwnedByNativeWidget();

  // It should be in the active desk container.
  EXPECT_TRUE(
      GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent()));

  // Set the z-order to float.
  widget->SetZOrderLevel(ui::ZOrderLevel::kFloatingWindow);
  // And it should in always on top container now.
  EXPECT_EQ(GetAlwaysOnTopContainer(), widget->GetNativeWindow()->parent());

  // Put the z-order back to normal.
  widget->SetZOrderLevel(ui::ZOrderLevel::kNormal);
  // It should go back to the active desk container.
  EXPECT_TRUE(
      GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent()));

  // Set the z-order again to the normal value.
  widget->SetZOrderLevel(ui::ZOrderLevel::kNormal);
  // Should have no effect and we are still in the the active desk container.
  EXPECT_TRUE(
      GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent()));

  widget->Close();
}

TEST_F(ShellTest, CreateModalWindow) {
  // Create a normal window.
  views::Widget* widget = TestWidgetBuilder().BuildOwnedByNativeWidget();

  // It should be in the active desk container.
  EXPECT_TRUE(
      GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent()));

  // Create a modal window.
  views::Widget* modal_widget = views::Widget::CreateWindowWithParent(
      CreateModalWidgetDelegate(), widget->GetNativeView());
  modal_widget->Show();

  // It should be in modal container.
  aura::Window* modal_container = Shell::GetContainer(
      Shell::GetPrimaryRootWindow(), kShellWindowId_SystemModalContainer);
  EXPECT_EQ(modal_container, modal_widget->GetNativeWindow()->parent());

  modal_widget->Close();
  widget->Close();
}

TEST_F(ShellTest, CreateLockScreenModalWindow) {
  // Create a normal window.
  views::Widget* widget = TestWidgetBuilder().BuildOwnedByNativeWidget();
  EXPECT_TRUE(widget->GetNativeView()->HasFocus());

  // It should be in the active desk container.
  EXPECT_TRUE(
      GetActiveDeskContainer()->Contains(widget->GetNativeWindow()->parent()));

  GetSessionControllerClient()->LockScreen();
  // Create a LockScreen window.
  views::Widget* lock_widget =
      TestWidgetBuilder().SetShow(false).BuildOwnedByNativeWidget();
  Shell::GetContainer(Shell::GetPrimaryRootWindow(),
                      kShellWindowId_LockScreenContainer)
      ->AddChild(lock_widget->GetNativeView());
  lock_widget->Show();
  EXPECT_TRUE(lock_widget->GetNativeView()->HasFocus());

  // It should be in LockScreen container.
  aura::Window* lock_screen = Shell::GetContainer(
      Shell::GetPrimaryRootWindow(), kShellWindowId_LockScreenContainer);
  EXPECT_EQ(lock_screen, lock_widget->GetNativeWindow()->parent());

  // Create a modal window with a lock window as parent.
  views::Widget* lock_modal_widget = views::Widget::CreateWindowWithParent(
      CreateModalWidgetDelegate(), lock_widget->GetNativeView());
  lock_modal_widget->Show();
  EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus());

  // It should be in LockScreen modal container.
  aura::Window* lock_modal_container =
      Shell::GetContainer(Shell::GetPrimaryRootWindow(),
                          kShellWindowId_LockSystemModalContainer);
  EXPECT_EQ(lock_modal_container,
            lock_modal_widget->GetNativeWindow()->parent());

  // Create a modal window with a normal window as parent.
  views::Widget* modal_widget = views::Widget::CreateWindowWithParent(
      CreateModalWidgetDelegate(), widget->GetNativeView());
  modal_widget->Show();
  // Window on lock screen shouldn't lost focus.
  EXPECT_FALSE(modal_widget->GetNativeView()->HasFocus());
  EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus());

  // It should be in non-LockScreen modal container.
  aura::Window* modal_container = Shell::GetContainer(
      Shell::GetPrimaryRootWindow(), kShellWindowId_SystemModalContainer);
  EXPECT_EQ(modal_container, modal_widget->GetNativeWindow()->parent());

  // Modal widget without parent, caused crash see crbug.com/226141
  views::Widget* modal_dialog = views::DialogDelegate::CreateDialogWidget(
      CreateModalWidgetDelegate(), GetContext(), nullptr);

  modal_dialog->Show();
  EXPECT_FALSE(modal_dialog->GetNativeView()->HasFocus());
  EXPECT_TRUE(lock_modal_widget->GetNativeView()->HasFocus());

  modal_dialog->Close();
  modal_widget->Close();
  modal_widget->Close();
  lock_modal_widget->Close();
  lock_widget->Close();
  widget->Close();
}

TEST_F(ShellTest, IsScreenLocked) {
  SessionControllerImpl* controller = Shell::Get()->session_controller();
  GetSessionControllerClient()->LockScreen();
  EXPECT_TRUE(controller->IsScreenLocked());
  GetSessionControllerClient()->UnlockScreen();
  EXPECT_FALSE(controller->IsScreenLocked());
}

TEST_F(ShellTest, LockScreenClosesActiveMenu) {
  SimpleMenuDelegate menu_delegate;
  std::unique_ptr<ui::SimpleMenuModel> menu_model(
      new ui::SimpleMenuModel(&menu_delegate));
  menu_model->AddItem(0, u"Menu item");
  views::Widget* widget = Shell::GetPrimaryRootWindowController()
                              ->wallpaper_widget_controller()
                              ->GetWidget();
  std::unique_ptr<views::MenuRunner> menu_runner(
      new views::MenuRunner(menu_model.get(), views::MenuRunner::CONTEXT_MENU));

  menu_runner->RunMenuAt(widget, nullptr, gfx::Rect(),
                         views::MenuAnchorPosition::kTopLeft,
                         ui::MENU_SOURCE_MOUSE);
  LockScreenAndVerifyMenuClosed();
}

TEST_F(ShellTest, ManagedWindowModeBasics) {
  // We start with the usual window containers.
  ExpectAllContainers();
  // Shelf is visible.
  ShelfWidget* shelf_widget = GetPrimaryShelf()->shelf_widget();
  EXPECT_TRUE(shelf_widget->IsVisible());
  // Shelf is at bottom-left of screen.
  EXPECT_EQ(0, shelf_widget->GetWindowBoundsInScreen().x());
  EXPECT_EQ(
      Shell::GetPrimaryRootWindow()->GetHost()->GetBoundsInPixels().height(),
      shelf_widget->GetWindowBoundsInScreen().bottom());
  // We have a wallpaper but not a bare layer.
  // TODO (antrim): enable once we find out why it fails component build.
  //  WallpaperWidgetController* wallpaper =
  //      Shell::GetPrimaryRootWindow()->
  //          GetProperty(kWindowDesktopComponent);
  //  EXPECT_TRUE(wallpaper);
  //  EXPECT_TRUE(wallpaper->widget());
  //  EXPECT_FALSE(wallpaper->layer());

  // Create a normal window.  It is not maximized.
  views::Widget* widget = TestWidgetBuilder()
                              .SetBounds(gfx::Rect(11, 22, 300, 400))
                              .BuildOwnedByNativeWidget();
  EXPECT_FALSE(widget->IsMaximized());

  // Clean up.
  widget->Close();
}

TEST_F(ShellTest, FullscreenWindowHidesShelf) {
  ExpectAllContainers();

  // Create a normal window.  It is not maximized.
  views::Widget* widget = TestWidgetBuilder()
                              .SetBounds(gfx::Rect(11, 22, 300, 400))
                              .BuildOwnedByNativeWidget();
  EXPECT_FALSE(widget->IsMaximized());

  // Shelf defaults to visible.
  EXPECT_EQ(SHELF_VISIBLE, Shell::GetPrimaryRootWindowController()
                               ->GetShelfLayoutManager()
                               ->visibility_state());

  // Fullscreen window hides it.
  widget->SetFullscreen(true);
  EXPECT_EQ(SHELF_HIDDEN, Shell::GetPrimaryRootWindowController()
                              ->GetShelfLayoutManager()
                              ->visibility_state());

  // Restoring the window restores it.
  widget->Restore();
  EXPECT_EQ(SHELF_VISIBLE, Shell::GetPrimaryRootWindowController()
                               ->GetShelfLayoutManager()
                               ->visibility_state());

  // Clean up.
  widget->Close();
}

// Various assertions around auto-hide behavior.
// TODO(jamescook): Move this to ShelfTest.
TEST_F(ShellTest, ToggleAutoHide) {
  std::unique_ptr<aura::Window> window =
      std::make_unique<aura::Window>(nullptr);
  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
  window->SetType(aura::client::WINDOW_TYPE_NORMAL);
  window->Init(ui::LAYER_TEXTURED);
  ParentWindowInPrimaryRootWindow(window.get());
  window->Show();
  wm::ActivateWindow(window.get());

  Shelf* shelf = GetPrimaryShelf();
  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
  EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());

  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
  EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());

  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
  EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());

  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
  EXPECT_EQ(ShelfAutoHideBehavior::kAlways, shelf->auto_hide_behavior());

  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
  EXPECT_EQ(ShelfAutoHideBehavior::kNever, shelf->auto_hide_behavior());
}

// Tests that the cursor-filter is ahead of the drag-drop controller in the
// pre-target list.
TEST_F(ShellTest, TestPreTargetHandlerOrder) {
  Shell* shell = Shell::Get();
  ui::EventTargetTestApi test_api(shell);
  ShellTestApi shell_test_api;

  ui::EventHandlerList handlers = test_api.GetPreTargetHandlers();
  ui::EventHandlerList::const_iterator cursor_filter =
      std::find(handlers.begin(), handlers.end(), shell->mouse_cursor_filter());
  ui::EventHandlerList::const_iterator drag_drop = std::find(
      handlers.begin(), handlers.end(), shell_test_api.drag_drop_controller());
  EXPECT_NE(handlers.end(), cursor_filter);
  EXPECT_NE(handlers.end(), drag_drop);
  EXPECT_GT(drag_drop, cursor_filter);
}

// Verifies an EventHandler added to Env gets notified from EventGenerator.
TEST_F(ShellTest, EnvPreTargetHandler) {
  ui::test::TestEventHandler event_handler;
  aura::Env::GetInstance()->AddPreTargetHandler(&event_handler);
  ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
  generator.MoveMouseBy(1, 1);
  EXPECT_NE(0, event_handler.num_mouse_events());
  aura::Env::GetInstance()->RemovePreTargetHandler(&event_handler);
}

// Verifies that pressing tab on an empty shell (one with no windows visible)
// will put focus on the shelf. This enables keyboard only users to get to the
// shelf without knowing the more obscure accelerators. Tab should move focus to
// the home button, shift + tab to the status widget. From there, normal shelf
// tab behaviour takes over, and the shell no longer catches that event.
TEST_F(ShellTest, NoWindowTabFocus) {
  ExpectAllContainers();

  StatusAreaWidget* status_area_widget =
      GetPrimaryShelf()->status_area_widget();
  ShelfNavigationWidget* home_button = GetPrimaryShelf()->navigation_widget();

  // Create a normal window.  It is not maximized.
  auto widget = CreateTestWidget();

  // Hit tab with window open, and expect that focus is not on the navigation
  // widget or status widget.
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_FALSE(home_button->GetNativeView()->HasFocus());
  EXPECT_FALSE(status_area_widget->GetNativeView()->HasFocus());

  // Minimize the window, hit tab and expect that focus is on the launcher.
  widget->Minimize();
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_TRUE(home_button->GetNativeView()->HasFocus());

  // Show (to steal focus back before continuing testing) and close the window.
  widget->Show();
  widget->Close();
  EXPECT_FALSE(home_button->GetNativeView()->HasFocus());

  // Confirm that pressing tab when overview mode is open does not go to home
  // button. Tab should be handled by overview mode and not hit the shell event
  // handler.
  EnterOverview();
  PressAndReleaseKey(ui::VKEY_TAB);
  EXPECT_FALSE(home_button->GetNativeView()->HasFocus());
  ExitOverview();

  // Hit shift tab and expect that focus is on status widget.
  PressAndReleaseKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
  EXPECT_TRUE(status_area_widget->GetNativeView()->HasFocus());
}

// This verifies WindowObservers are removed when a window is destroyed after
// the Shell is destroyed. This scenario (aura::Windows being deleted after the
// Shell) occurs if someone is holding a reference to an unparented Window, as
// is the case with a RenderWidgetHostViewAura that isn't on screen. As long as
// everything is ok, we won't crash. If there is a bug, window's destructor will
// notify some deleted object (say VideoDetector or ActivationController) and
// this will crash.
class ShellTest2 : public AshTestBase {
 public:
  ShellTest2() = default;
  ~ShellTest2() override = default;

 protected:
  std::unique_ptr<aura::Window> window_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ShellTest2);
};

TEST_F(ShellTest2, DontCrashWhenWindowDeleted) {
  window_ = std::make_unique<aura::Window>(nullptr,
                                           aura::client::WINDOW_TYPE_UNKNOWN);
  window_->Init(ui::LAYER_NOT_DRAWN);
}

using ShellLoginTest = NoSessionAshTestBase;

TEST_F(ShellLoginTest, DragAndDropDisabledBeforeLogin) {
  DragDropController* drag_drop_controller =
      ShellTestApi().drag_drop_controller();
  DragDropControllerTestApi drag_drop_controller_test_api(drag_drop_controller);
  EXPECT_FALSE(drag_drop_controller_test_api.enabled());

  SimulateUserLogin("user1@test.com");
  EXPECT_TRUE(drag_drop_controller_test_api.enabled());
}

using NoDuplicateShellContainerIdsTest = AshTestBase;

TEST_F(NoDuplicateShellContainerIdsTest, ValidateContainersIds) {
  ExpectAllContainers();
}

}  // namespace ash
