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

#include <queue>
#include <vector>

#include "ash/ash_constants.h"
#include "ash/ash_switches.h"
#include "ash/desktop_background/desktop_background_controller.h"
#include "ash/desktop_background/desktop_background_widget_controller.h"
#include "ash/desktop_background/user_wallpaper_delegate.h"
#include "ash/display/display_manager.h"
#include "ash/focus_cycler.h"
#include "ash/high_contrast/high_contrast_controller.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/root_window_settings.h"
#include "ash/session/session_state_delegate.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_types.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_factory.h"
#include "ash/shell_window_ids.h"
#include "ash/switchable_windows.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/touch/touch_hud_debug.h"
#include "ash/touch/touch_hud_projection.h"
#include "ash/touch/touch_observer_hud.h"
#include "ash/wm/always_on_top_controller.h"
#include "ash/wm/dock/docked_window_layout_manager.h"
#include "ash/wm/lock_layout_manager.h"
#include "ash/wm/panels/attached_panel_window_targeter.h"
#include "ash/wm/panels/panel_layout_manager.h"
#include "ash/wm/panels/panel_window_event_handler.h"
#include "ash/wm/root_window_layout_manager.h"
#include "ash/wm/screen_dimmer.h"
#include "ash/wm/stacking_controller.h"
#include "ash/wm/status_area_layout_manager.h"
#include "ash/wm/system_background_controller.h"
#include "ash/wm/system_modal_container_layout_manager.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/workspace_layout_manager.h"
#include "ash/wm/workspace_controller.h"
#include "base/command_line.h"
#include "base/time/time.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tracker.h"
#include "ui/base/hit_test.h"
#include "ui/base/models/menu_model.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/view_model.h"
#include "ui/views/view_model_utils.h"
#include "ui/wm/core/capture_controller.h"
#include "ui/wm/core/easy_resize_window_targeter.h"
#include "ui/wm/core/visibility_controller.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/drag_drop_client.h"
#include "ui/wm/public/tooltip_client.h"
#include "ui/wm/public/window_types.h"

#if defined(OS_CHROMEOS)
#include "ash/system/tray_accessibility.h"
#include "ash/wm/boot_splash_screen_chromeos.h"
#include "ui/chromeos/touch_exploration_controller.h"
#endif

namespace ash {
namespace {

#if defined(OS_CHROMEOS)
// Duration for the animation that hides the boot splash screen, in
// milliseconds.  This should be short enough in relation to
// wm/window_animation.cc's brightness/grayscale fade animation that the login
// background image animation isn't hidden by the splash screen animation.
const int kBootSplashScreenHideDurationMs = 500;
#endif

// Creates a new window for use as a container.
aura::Window* CreateContainer(int window_id,
                              const char* name,
                              aura::Window* parent) {
  aura::Window* container = new aura::Window(NULL);
  container->set_id(window_id);
  container->SetName(name);
  container->Init(aura::WINDOW_LAYER_NOT_DRAWN);
  parent->AddChild(container);
  if (window_id != kShellWindowId_UnparentedControlContainer)
    container->Show();
  return container;
}

float ToRelativeValue(int value, int src, int dst) {
  return static_cast<float>(value) / static_cast<float>(src) * dst;
}

void MoveOriginRelativeToSize(const gfx::Size& src_size,
                                const gfx::Size& dst_size,
                                gfx::Rect* bounds_in_out) {
  gfx::Point origin = bounds_in_out->origin();
  bounds_in_out->set_origin(gfx::Point(
      ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
      ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
}

// Reparents |window| to |new_parent|.
void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
  const gfx::Size src_size = window->parent()->bounds().size();
  const gfx::Size dst_size = new_parent->bounds().size();
  // Update the restore bounds to make it relative to the display.
  wm::WindowState* state = wm::GetWindowState(window);
  gfx::Rect restore_bounds;
  bool has_restore_bounds = state->HasRestoreBounds();

  bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
                       new_parent->id() != kShellWindowId_DockedContainer;
  gfx::Rect local_bounds;
  if (update_bounds) {
    local_bounds = state->window()->bounds();
    MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
  }

  if (has_restore_bounds) {
    restore_bounds = state->GetRestoreBoundsInParent();
    MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
  }

  new_parent->AddChild(window);

  // Docked windows have bounds handled by the layout manager in AddChild().
  if (update_bounds)
    window->SetBounds(local_bounds);

  if (has_restore_bounds)
    state->SetRestoreBoundsInParent(restore_bounds);
}

// Reparents the appropriate set of windows from |src| to |dst|.
void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
  // Set of windows to move.
  const int kContainerIdsToMove[] = {
      kShellWindowId_DefaultContainer,
      kShellWindowId_DockedContainer,
      kShellWindowId_PanelContainer,
      kShellWindowId_AlwaysOnTopContainer,
      kShellWindowId_SystemModalContainer,
      kShellWindowId_LockSystemModalContainer,
      kShellWindowId_UnparentedControlContainer, };
  for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
    int id = kContainerIdsToMove[i];
    aura::Window* src_container = Shell::GetContainer(src, id);
    aura::Window* dst_container = Shell::GetContainer(dst, id);
    while (!src_container->children().empty()) {
      // Restart iteration from the source container windows each time as they
      // may change as a result of moving other windows.
      aura::Window::Windows::const_iterator iter =
          src_container->children().begin();
      while (iter != src_container->children().end() &&
             SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
        ++iter;
      }
      // If the entire window list is modal background windows then stop.
      if (iter == src_container->children().end())
        break;
      ReparentWindow(*iter, dst_container);
    }
  }
}

// Mark the container window so that a widget added to this container will
// use the virtual screeen coordinates instead of parent.
void SetUsesScreenCoordinates(aura::Window* container) {
  container->SetProperty(kUsesScreenCoordinatesKey, true);
}

// Mark the container window so that a widget added to this container will
// say in the same root window regardless of the bounds specified.
void DescendantShouldStayInSameRootWindow(aura::Window* container) {
  container->SetProperty(kStayInSameRootWindowKey, true);
}

void SetUsesEasyResizeTargeter(aura::Window* container) {
  gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
                           -kResizeOutsideBoundsSize,
                           -kResizeOutsideBoundsSize,
                           -kResizeOutsideBoundsSize);
  gfx::Insets touch_extend = mouse_extend.Scale(
      kResizeOutsideBoundsScaleForTouch);
  container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
      new ::wm::EasyResizeWindowTargeter(container, mouse_extend,
                                         touch_extend)));
}

// A window delegate which does nothing. Used to create a window that
// is a event target, but do nothing.
class EmptyWindowDelegate : public aura::WindowDelegate {
 public:
  EmptyWindowDelegate() {}
  virtual ~EmptyWindowDelegate() {}

  // aura::WindowDelegate overrides:
  virtual gfx::Size GetMinimumSize() const OVERRIDE {
    return gfx::Size();
  }
  virtual gfx::Size GetMaximumSize() const OVERRIDE {
    return gfx::Size();
  }
  virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
                               const gfx::Rect& new_bounds) OVERRIDE {
  }
  virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
    return gfx::kNullCursor;
  }
  virtual int GetNonClientComponent(
      const gfx::Point& point) const OVERRIDE {
    return HTNOWHERE;
  }
  virtual bool ShouldDescendIntoChildForEventHandling(
      aura::Window* child,
      const gfx::Point& location) OVERRIDE {
    return false;
  }
  virtual bool CanFocus() OVERRIDE {
    return false;
  }
  virtual void OnCaptureLost() OVERRIDE {
  }
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
  }
  virtual void OnDeviceScaleFactorChanged(
      float device_scale_factor) OVERRIDE {
  }
  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {}
  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
    delete this;
  }
  virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
  }
  virtual bool HasHitTestMask() const OVERRIDE {
    return false;
  }
  virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}

 private:
  DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
};

#if defined(OS_CHROMEOS)
// Responsible for initializing TouchExplorationController when spoken
// feedback is on.
class CrosAccessibilityObserver : public AccessibilityObserver {
 public:
  explicit CrosAccessibilityObserver(
      RootWindowController* root_window_controller)
      : root_window_controller_(root_window_controller) {
    Shell::GetInstance()->system_tray_notifier()->
        AddAccessibilityObserver(this);
    UpdateTouchExplorationState();
  }

  virtual ~CrosAccessibilityObserver() {
    SystemTrayNotifier* system_tray_notifier =
        Shell::GetInstance()->system_tray_notifier();
    if (system_tray_notifier)
      system_tray_notifier->RemoveAccessibilityObserver(this);
  }

 private:
  void UpdateTouchExplorationState() {
    AccessibilityDelegate* delegate =
        Shell::GetInstance()->accessibility_delegate();
    bool enabled = delegate->IsSpokenFeedbackEnabled();

    if (enabled && !touch_exploration_controller_.get()) {
      touch_exploration_controller_.reset(
          new ui::TouchExplorationController(
              root_window_controller_->GetRootWindow()));
    } else if (!enabled) {
      touch_exploration_controller_.reset();
    }
  }

  // Overridden from AccessibilityObserver.
  virtual void OnAccessibilityModeChanged(
      AccessibilityNotificationVisibility notify) OVERRIDE {
    UpdateTouchExplorationState();
  }

  scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_;
  RootWindowController* root_window_controller_;

  DISALLOW_COPY_AND_ASSIGN(CrosAccessibilityObserver);
};
#endif  // OS_CHROMEOS

}  // namespace

void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
  RootWindowController* controller = new RootWindowController(host);
  controller->Init(RootWindowController::PRIMARY,
                   Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
}

void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
  RootWindowController* controller = new RootWindowController(host);
  controller->Init(RootWindowController::SECONDARY, false /* first run */);
}

void RootWindowController::CreateForVirtualKeyboardDisplay(
    AshWindowTreeHost* host) {
  RootWindowController* controller = new RootWindowController(host);
  controller->Init(RootWindowController::VIRTUAL_KEYBOARD,
                   false /* first run */);
}

// static
RootWindowController* RootWindowController::ForShelf(
    const aura::Window* window) {
  return GetRootWindowController(window->GetRootWindow());
}

// static
RootWindowController* RootWindowController::ForWindow(
    const aura::Window* window) {
  return GetRootWindowController(window->GetRootWindow());
}

// static
RootWindowController* RootWindowController::ForTargetRootWindow() {
  return GetRootWindowController(Shell::GetTargetRootWindow());
}

// static
aura::Window* RootWindowController::GetContainerForWindow(
    aura::Window* window) {
  aura::Window* container = window->parent();
  while (container && container->type() != ui::wm::WINDOW_TYPE_UNKNOWN)
    container = container->parent();
  return container;
}

RootWindowController::~RootWindowController() {
  Shutdown();
  ash_host_.reset();
  // The CaptureClient needs to be around for as long as the RootWindow is
  // valid.
  capture_client_.reset();
}

aura::WindowTreeHost* RootWindowController::GetHost() {
  return ash_host_->AsWindowTreeHost();
}

const aura::WindowTreeHost* RootWindowController::GetHost() const {
  return ash_host_->AsWindowTreeHost();
}

aura::Window* RootWindowController::GetRootWindow() {
  return GetHost()->window();
}

const aura::Window* RootWindowController::GetRootWindow() const {
  return GetHost()->window();
}

void RootWindowController::SetWallpaperController(
    DesktopBackgroundWidgetController* controller) {
  wallpaper_controller_.reset(controller);
}

void RootWindowController::SetAnimatingWallpaperController(
    AnimatingDesktopController* controller) {
  if (animating_wallpaper_controller_.get())
    animating_wallpaper_controller_->StopAnimating();
  animating_wallpaper_controller_.reset(controller);
}

void RootWindowController::Shutdown() {
  Shell* shell = Shell::GetInstance();
  shell->RemoveShellObserver(this);

#if defined(OS_CHROMEOS)
  if (cros_accessibility_observer_) {
    cros_accessibility_observer_.reset();
  }
#endif

  if (animating_wallpaper_controller_.get())
    animating_wallpaper_controller_->StopAnimating();
  wallpaper_controller_.reset();
  animating_wallpaper_controller_.reset();
  aura::Window* root_window = GetRootWindow();
  // Change the target root window before closing child windows. If any child
  // being removed triggers a relayout of the shelf it will try to build a
  // window list adding windows from the target root window's containers which
  // may have already gone away.
  if (Shell::GetTargetRootWindow() == root_window) {
    shell->set_target_root_window(
        Shell::GetPrimaryRootWindow() == root_window
            ? NULL
            : Shell::GetPrimaryRootWindow());
  }

  CloseChildWindows();
  GetRootWindowSettings(root_window)->controller = NULL;
  screen_dimmer_.reset();
  workspace_controller_.reset();
  // Forget with the display ID so that display lookup
  // ends up with invalid display.
  GetRootWindowSettings(root_window)->display_id =
      gfx::Display::kInvalidDisplayID;
  ash_host_->PrepareForShutdown();

  system_background_.reset();
  aura::client::SetScreenPositionClient(root_window, NULL);
}

SystemModalContainerLayoutManager*
RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
  aura::Window* modal_container = NULL;
  if (window) {
    aura::Window* window_container = GetContainerForWindow(window);
    if (window_container &&
        window_container->id() >= kShellWindowId_LockScreenContainer) {
      modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
    } else {
      modal_container = GetContainer(kShellWindowId_SystemModalContainer);
    }
  } else {
    int modal_window_id = Shell::GetInstance()->session_state_delegate()
        ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
                                   kShellWindowId_SystemModalContainer;
    modal_container = GetContainer(modal_window_id);
  }
  return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
      modal_container->layout_manager()) : NULL;
}

aura::Window* RootWindowController::GetContainer(int container_id) {
  return GetRootWindow()->GetChildById(container_id);
}

const aura::Window* RootWindowController::GetContainer(int container_id) const {
  return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
}

void RootWindowController::ShowShelf() {
  if (!shelf_->shelf())
    return;
  shelf_->shelf()->SetVisible(true);
  shelf_->status_area_widget()->Show();
}

void RootWindowController::OnShelfCreated() {
  if (panel_layout_manager_)
    panel_layout_manager_->SetShelf(shelf_->shelf());
  if (docked_layout_manager_) {
    docked_layout_manager_->SetShelf(shelf_->shelf());
    if (shelf_->shelf_layout_manager())
      docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
  }

  // Notify shell observers that the shelf has been created.
  Shell::GetInstance()->OnShelfCreatedForRootWindow(GetRootWindow());
}

void RootWindowController::UpdateAfterLoginStatusChange(
    user::LoginStatus status) {
  if (status != user::LOGGED_IN_NONE)
    mouse_event_target_.reset();
  if (shelf_->status_area_widget())
    shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
}

void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
#if defined(OS_CHROMEOS)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kAshAnimateFromBootSplashScreen) &&
      boot_splash_screen_.get()) {
    // Make the splash screen fade out so it doesn't obscure the desktop
    // wallpaper's brightness/grayscale animation.
    boot_splash_screen_->StartHideAnimation(
        base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
  }
#endif
}

void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
  // Make sure the wallpaper is visible.
  system_background_->SetColor(SK_ColorBLACK);
#if defined(OS_CHROMEOS)
  boot_splash_screen_.reset();
#endif

  Shell::GetInstance()->user_wallpaper_delegate()->
      OnWallpaperAnimationFinished();
  // Only removes old component when wallpaper animation finished. If we
  // remove the old one before the new wallpaper is done fading in there will
  // be a white flash during the animation.
  if (animating_wallpaper_controller()) {
    DesktopBackgroundWidgetController* controller =
        animating_wallpaper_controller()->GetController(true);
    // |desktop_widget_| should be the same animating widget we try to move
    // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
    // before move it to |kDesktopController|.
    DCHECK_EQ(controller->widget(), widget);
    // Release the old controller and close its background widget.
    SetWallpaperController(controller);
  }
}

void RootWindowController::CloseChildWindows() {
  mouse_event_target_.reset();

  // Remove observer as deactivating keyboard causes |docked_layout_manager_|
  // to fire notifications.
  if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
    docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());

  // Deactivate keyboard container before closing child windows and shutting
  // down associated layout managers.
  DeactivateKeyboard(keyboard::KeyboardController::GetInstance());

  // panel_layout_manager_ needs to be shut down before windows are destroyed.
  if (panel_layout_manager_) {
    panel_layout_manager_->Shutdown();
    panel_layout_manager_ = NULL;
  }
  // docked_layout_manager_ needs to be shut down before windows are destroyed.
  if (docked_layout_manager_) {
    docked_layout_manager_->Shutdown();
    docked_layout_manager_ = NULL;
  }
  aura::Window* root_window = GetRootWindow();
  aura::client::SetDragDropClient(root_window, NULL);

  // TODO(harrym): Remove when Status Area Widget is a child view.
  if (shelf_) {
    shelf_->ShutdownStatusAreaWidget();

    if (shelf_->shelf_layout_manager())
      shelf_->shelf_layout_manager()->PrepareForShutdown();
  }

  // Close background widget first as it depends on tooltip.
  wallpaper_controller_.reset();
  animating_wallpaper_controller_.reset();

  workspace_controller_.reset();
  aura::client::SetTooltipClient(root_window, NULL);

  // Explicitly destroy top level windows. We do this as during part of
  // destruction such windows may query the RootWindow for state.
  std::queue<aura::Window*> non_toplevel_windows;
  non_toplevel_windows.push(root_window);
  while (!non_toplevel_windows.empty()) {
    aura::Window* non_toplevel_window = non_toplevel_windows.front();
    non_toplevel_windows.pop();
    aura::WindowTracker toplevel_windows;
    for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
      aura::Window* child = non_toplevel_window->children()[i];
      if (!child->owned_by_parent())
        continue;
      if (child->delegate())
        toplevel_windows.Add(child);
      else
        non_toplevel_windows.push(child);
    }
    while (!toplevel_windows.windows().empty())
      delete *toplevel_windows.windows().begin();
  }
  // And then remove the containers.
  while (!root_window->children().empty()) {
    aura::Window* window = root_window->children()[0];
    if (window->owned_by_parent()) {
      delete window;
    } else {
      root_window->RemoveChild(window);
    }
  }

  shelf_.reset();
}

void RootWindowController::MoveWindowsTo(aura::Window* dst) {
  // Forget the shelf early so that shelf don't update itself using wrong
  // display info.
  workspace_controller_->SetShelf(NULL);
  ReparentAllWindows(GetRootWindow(), dst);
}

ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
  return shelf_->shelf_layout_manager();
}

SystemTray* RootWindowController::GetSystemTray() {
  // We assume in throughout the code that this will not return NULL. If code
  // triggers this for valid reasons, it should test status_area_widget first.
  CHECK(shelf_->status_area_widget());
  return shelf_->status_area_widget()->system_tray();
}

void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
                                           ui::MenuSourceType source_type) {
  DCHECK(Shell::GetInstance()->delegate());
  scoped_ptr<ui::MenuModel> menu_model(
      Shell::GetInstance()->delegate()->CreateContextMenu(
          GetRootWindow(), NULL, NULL));
  if (!menu_model)
    return;

  // Background controller may not be set yet if user clicked on status are
  // before initial animation completion. See crbug.com/222218
  if (!wallpaper_controller_.get())
    return;

  views::MenuRunner menu_runner(menu_model.get());
  if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
                            NULL,
                            gfx::Rect(location_in_screen, gfx::Size()),
                            views::MENU_ANCHOR_TOPLEFT,
                            source_type,
                            views::MenuRunner::CONTEXT_MENU) ==
      views::MenuRunner::MENU_DELETED) {
    return;
  }

  Shell::GetInstance()->UpdateShelfVisibility();
}

void RootWindowController::UpdateShelfVisibility() {
  shelf_->shelf_layout_manager()->UpdateVisibilityState();
}

const aura::Window* RootWindowController::GetWindowForFullscreenMode() const {
  const aura::Window* topmost_window = NULL;
  const aura::Window* active_window = wm::GetActiveWindow();
  if (active_window && active_window->GetRootWindow() == GetRootWindow() &&
      IsSwitchableContainer(active_window->parent())) {
    // Use the active window when it is on the current root window to determine
    // the fullscreen state to allow temporarily using a panel or docked window
    // (which are always above the default container) while a fullscreen
    // window is open. We only use the active window when in a switchable
    // container as the launcher should not exit fullscreen mode.
    topmost_window = active_window;
  } else {
    // Otherwise, use the topmost window on the root window's default container
    // when there is no active window on this root window.
    const aura::Window::Windows& windows =
        GetContainer(kShellWindowId_DefaultContainer)->children();
    for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
         iter != windows.rend(); ++iter) {
      if (((*iter)->type() == ui::wm::WINDOW_TYPE_NORMAL ||
           (*iter)->type() == ui::wm::WINDOW_TYPE_PANEL) &&
          (*iter)->layer()->GetTargetVisibility()) {
        topmost_window = *iter;
        break;
      }
    }
  }
  while (topmost_window) {
    if (wm::GetWindowState(topmost_window)->IsFullscreen())
      return topmost_window;
    topmost_window = ::wm::GetTransientParent(topmost_window);
  }
  return NULL;
}

void RootWindowController::ActivateKeyboard(
    keyboard::KeyboardController* keyboard_controller) {
  if (!keyboard::IsKeyboardEnabled() ||
      GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
    return;
  }
  DCHECK(keyboard_controller);
  if (!keyboard::IsKeyboardUsabilityExperimentEnabled()) {
    keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
    keyboard_controller->AddObserver(panel_layout_manager_);
    keyboard_controller->AddObserver(docked_layout_manager_);
    keyboard_controller->AddObserver(workspace_controller_->layout_manager());
    Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
  }
  aura::Window* parent = GetContainer(
      kShellWindowId_VirtualKeyboardParentContainer);
  DCHECK(parent);
  aura::Window* keyboard_container =
      keyboard_controller->GetContainerWindow();
  keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
  parent->AddChild(keyboard_container);
  // TODO(oshima): Bounds of keyboard container should be handled by
  // RootWindowLayoutManager. Remove this after fixed RootWindowLayoutManager.
  keyboard_container->SetBounds(parent->bounds());
}

void RootWindowController::DeactivateKeyboard(
    keyboard::KeyboardController* keyboard_controller) {
  if (!keyboard_controller ||
      !keyboard_controller->keyboard_container_initialized()) {
    return;
  }
  aura::Window* keyboard_container =
      keyboard_controller->GetContainerWindow();
  if (keyboard_container->GetRootWindow() == GetRootWindow()) {
    aura::Window* parent = GetContainer(
        kShellWindowId_VirtualKeyboardParentContainer);
    DCHECK(parent);
    parent->RemoveChild(keyboard_container);
    if (!keyboard::IsKeyboardUsabilityExperimentEnabled()) {
      // Virtual keyboard may be deactivated while still showing, notify all
      // observers that keyboard bounds changed to 0 before remove them.
      keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
      keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
      keyboard_controller->RemoveObserver(panel_layout_manager_);
      keyboard_controller->RemoveObserver(docked_layout_manager_);
      keyboard_controller->RemoveObserver(
          workspace_controller_->layout_manager());
      Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
    }
  }
}

bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
  aura::Window* parent = GetContainer(
      kShellWindowId_VirtualKeyboardParentContainer);
  return parent ? parent->Contains(window) : false;
}

////////////////////////////////////////////////////////////////////////////////
// RootWindowController, private:

RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
    : ash_host_(ash_host),
      root_window_layout_(NULL),
      docked_layout_manager_(NULL),
      panel_layout_manager_(NULL),
      touch_hud_debug_(NULL),
      touch_hud_projection_(NULL) {
  aura::Window* root_window = GetRootWindow();
  GetRootWindowSettings(root_window)->controller = this;
  screen_dimmer_.reset(new ScreenDimmer(root_window));

  stacking_controller_.reset(new StackingController);
  aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
  capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
}

void RootWindowController::Init(RootWindowType root_window_type,
                                bool first_run_after_boot) {
  aura::Window* root_window = GetRootWindow();
  Shell* shell = Shell::GetInstance();
  shell->InitRootWindow(root_window);

  ash_host_->AsWindowTreeHost()->SetCursor(ui::kCursorPointer);
  CreateContainersInRootWindow(root_window);

  if (root_window_type == VIRTUAL_KEYBOARD) {
    aura::Window* virtual_keyboard_parent_container = GetContainer(
        kShellWindowId_VirtualKeyboardParentContainer);
    virtual_keyboard_parent_container->SetBounds(root_window->bounds());
    shell->InitKeyboard();
    return;
  }

  CreateSystemBackground(first_run_after_boot);

  InitLayoutManagers();
  InitTouchHuds();

  if (Shell::GetPrimaryRootWindowController()->
      GetSystemModalLayoutManager(NULL)->has_modal_background()) {
    GetSystemModalLayoutManager(NULL)->CreateModalBackground();
  }

  shell->AddShellObserver(this);

  if (root_window_type == PRIMARY) {
    root_window_layout()->OnWindowResized();
    if (!keyboard::IsKeyboardUsabilityExperimentEnabled())
      shell->InitKeyboard();
  } else {
    root_window_layout()->OnWindowResized();
    ash_host_->AsWindowTreeHost()->Show();

    // Create a shelf if a user is already logged in.
    if (shell->session_state_delegate()->NumberOfLoggedInUsers())
      shelf()->CreateShelf();

    // Notify shell observers about new root window.
    shell->OnRootWindowAdded(root_window);
  }

#if defined(OS_CHROMEOS)
  if (!CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kAshDisableTouchExplorationMode)) {
    cros_accessibility_observer_.reset(new CrosAccessibilityObserver(this));
  }
#endif
}

void RootWindowController::InitLayoutManagers() {
  aura::Window* root_window = GetRootWindow();
  root_window_layout_ = new RootWindowLayoutManager(root_window);
  root_window->SetLayoutManager(root_window_layout_);

  aura::Window* default_container =
      GetContainer(kShellWindowId_DefaultContainer);
  // Workspace manager has its own layout managers.
  workspace_controller_.reset(
      new WorkspaceController(default_container));

  aura::Window* always_on_top_container =
      GetContainer(kShellWindowId_AlwaysOnTopContainer);
  always_on_top_container->SetLayoutManager(
      new WorkspaceLayoutManager(always_on_top_container));
  always_on_top_controller_.reset(new AlwaysOnTopController);
  always_on_top_controller_->SetAlwaysOnTopContainer(always_on_top_container);

  DCHECK(!shelf_.get());
  aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
  // TODO(harrym): Remove when status area is view.
  aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
  shelf_.reset(new ShelfWidget(
      shelf_container, status_container, workspace_controller()));

  if (!Shell::GetInstance()->session_state_delegate()->
      IsActiveUserSessionStarted()) {
    // This window exists only to be a event target on login screen.
    // It does not have to handle events, nor be visible.
    mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
    mouse_event_target_->Init(aura::WINDOW_LAYER_NOT_DRAWN);

    aura::Window* lock_background_container =
        GetContainer(kShellWindowId_LockScreenBackgroundContainer);
    lock_background_container->AddChild(mouse_event_target_.get());
    mouse_event_target_->Show();
  }

  // Create Docked windows layout manager
  aura::Window* docked_container = GetContainer(kShellWindowId_DockedContainer);
  docked_layout_manager_ =
      new DockedWindowLayoutManager(docked_container, workspace_controller());
  docked_container->SetLayoutManager(docked_layout_manager_);

  // Create Panel layout manager
  aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
  panel_layout_manager_ = new PanelLayoutManager(panel_container);
  panel_container->SetLayoutManager(panel_layout_manager_);
  panel_container_handler_.reset(new PanelWindowEventHandler);
  panel_container->AddPreTargetHandler(panel_container_handler_.get());

  // Install an AttachedPanelWindowTargeter on the panel container to make it
  // easier to correctly target shelf buttons with touch.
  gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
                           -kResizeOutsideBoundsSize,
                           -kResizeOutsideBoundsSize,
                           -kResizeOutsideBoundsSize);
  gfx::Insets touch_extend = mouse_extend.Scale(
      kResizeOutsideBoundsScaleForTouch);
  panel_container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
      new AttachedPanelWindowTargeter(panel_container,
                                      mouse_extend,
                                      touch_extend,
                                      panel_layout_manager_)));
}

void RootWindowController::InitTouchHuds() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kAshTouchHud))
    set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
  if (Shell::GetInstance()->is_touch_hud_projection_enabled())
    EnableTouchHudProjection();
}

void RootWindowController::CreateSystemBackground(
    bool is_first_run_after_boot) {
  SkColor color = SK_ColorBLACK;
#if defined(OS_CHROMEOS)
  if (is_first_run_after_boot)
    color = kChromeOsBootColor;
#endif
  system_background_.reset(
      new SystemBackgroundController(GetRootWindow(), color));

#if defined(OS_CHROMEOS)
  // Make a copy of the system's boot splash screen so we can composite it
  // onscreen until the desktop background is ready.
  if (is_first_run_after_boot &&
      (CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kAshCopyHostBackgroundAtBoot) ||
       CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kAshAnimateFromBootSplashScreen)))
    boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
#endif
}

void RootWindowController::CreateContainersInRootWindow(
    aura::Window* root_window) {
  // These containers are just used by PowerButtonController to animate groups
  // of containers simultaneously without messing up the current transformations
  // on those containers. These are direct children of the root window; all of
  // the other containers are their children.

  // The desktop background container is not part of the lock animation, so it
  // is not included in those animate groups.
  // When screen is locked desktop background is moved to lock screen background
  // container (moved back on unlock). We want to make sure that there's an
  // opaque layer occluding the non-lock-screen layers.
  aura::Window* desktop_background_container = CreateContainer(
      kShellWindowId_DesktopBackgroundContainer,
      "DesktopBackgroundContainer",
      root_window);
  ::wm::SetChildWindowVisibilityChangesAnimated(desktop_background_container);

  aura::Window* non_lock_screen_containers = CreateContainer(
      kShellWindowId_NonLockScreenContainersContainer,
      "NonLockScreenContainersContainer",
      root_window);

  aura::Window* lock_background_containers = CreateContainer(
      kShellWindowId_LockScreenBackgroundContainer,
      "LockScreenBackgroundContainer",
      root_window);
  ::wm::SetChildWindowVisibilityChangesAnimated(lock_background_containers);

  aura::Window* lock_screen_containers = CreateContainer(
      kShellWindowId_LockScreenContainersContainer,
      "LockScreenContainersContainer",
      root_window);
  aura::Window* lock_screen_related_containers = CreateContainer(
      kShellWindowId_LockScreenRelatedContainersContainer,
      "LockScreenRelatedContainersContainer",
      root_window);

  CreateContainer(kShellWindowId_UnparentedControlContainer,
                  "UnparentedControlContainer",
                  non_lock_screen_containers);

  aura::Window* default_container = CreateContainer(
      kShellWindowId_DefaultContainer,
      "DefaultContainer",
      non_lock_screen_containers);
  ::wm::SetChildWindowVisibilityChangesAnimated(default_container);
  SetUsesScreenCoordinates(default_container);
  SetUsesEasyResizeTargeter(default_container);

  aura::Window* always_on_top_container = CreateContainer(
      kShellWindowId_AlwaysOnTopContainer,
      "AlwaysOnTopContainer",
      non_lock_screen_containers);
  ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
  SetUsesScreenCoordinates(always_on_top_container);

  aura::Window* docked_container = CreateContainer(
      kShellWindowId_DockedContainer,
      "DockedContainer",
      non_lock_screen_containers);
  ::wm::SetChildWindowVisibilityChangesAnimated(docked_container);
  SetUsesScreenCoordinates(docked_container);
  SetUsesEasyResizeTargeter(docked_container);

  aura::Window* shelf_container =
      CreateContainer(kShellWindowId_ShelfContainer,
                      "ShelfContainer",
                      non_lock_screen_containers);
  SetUsesScreenCoordinates(shelf_container);
  DescendantShouldStayInSameRootWindow(shelf_container);

  aura::Window* panel_container = CreateContainer(
      kShellWindowId_PanelContainer,
      "PanelContainer",
      non_lock_screen_containers);
  SetUsesScreenCoordinates(panel_container);

  aura::Window* shelf_bubble_container =
      CreateContainer(kShellWindowId_ShelfBubbleContainer,
                      "ShelfBubbleContainer",
                      non_lock_screen_containers);
  SetUsesScreenCoordinates(shelf_bubble_container);
  DescendantShouldStayInSameRootWindow(shelf_bubble_container);

  aura::Window* app_list_container =
      CreateContainer(kShellWindowId_AppListContainer,
                      "AppListContainer",
                      non_lock_screen_containers);
  SetUsesScreenCoordinates(app_list_container);

  aura::Window* modal_container = CreateContainer(
      kShellWindowId_SystemModalContainer,
      "SystemModalContainer",
      non_lock_screen_containers);
  modal_container->SetLayoutManager(
      new SystemModalContainerLayoutManager(modal_container));
  ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
  SetUsesScreenCoordinates(modal_container);
  SetUsesEasyResizeTargeter(modal_container);

  // TODO(beng): Figure out if we can make this use
  // SystemModalContainerEventFilter instead of stops_event_propagation.
  aura::Window* lock_container = CreateContainer(
      kShellWindowId_LockScreenContainer,
      "LockScreenContainer",
      lock_screen_containers);
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kAshDisableLockLayoutManager)) {
    lock_container->SetLayoutManager(
            new WorkspaceLayoutManager(lock_container));
  } else {
    lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
  }
  SetUsesScreenCoordinates(lock_container);
  // TODO(beng): stopsevents

  aura::Window* lock_modal_container = CreateContainer(
      kShellWindowId_LockSystemModalContainer,
      "LockSystemModalContainer",
      lock_screen_containers);
  lock_modal_container->SetLayoutManager(
      new SystemModalContainerLayoutManager(lock_modal_container));
  ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
  SetUsesScreenCoordinates(lock_modal_container);
  SetUsesEasyResizeTargeter(lock_modal_container);

  aura::Window* status_container =
      CreateContainer(kShellWindowId_StatusContainer,
                      "StatusContainer",
                      lock_screen_related_containers);
  SetUsesScreenCoordinates(status_container);
  DescendantShouldStayInSameRootWindow(status_container);

  aura::Window* settings_bubble_container = CreateContainer(
      kShellWindowId_SettingBubbleContainer,
      "SettingBubbleContainer",
      lock_screen_related_containers);
  ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
  SetUsesScreenCoordinates(settings_bubble_container);
  DescendantShouldStayInSameRootWindow(settings_bubble_container);

  aura::Window* menu_container = CreateContainer(
      kShellWindowId_MenuContainer,
      "MenuContainer",
      lock_screen_related_containers);
  ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
  SetUsesScreenCoordinates(menu_container);

  aura::Window* drag_drop_container = CreateContainer(
      kShellWindowId_DragImageAndTooltipContainer,
      "DragImageAndTooltipContainer",
      lock_screen_related_containers);
  ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
  SetUsesScreenCoordinates(drag_drop_container);

  aura::Window* overlay_container = CreateContainer(
      kShellWindowId_OverlayContainer,
      "OverlayContainer",
      lock_screen_related_containers);
  SetUsesScreenCoordinates(overlay_container);

  aura::Window* virtual_keyboard_parent_container = CreateContainer(
      kShellWindowId_VirtualKeyboardParentContainer,
      "VirtualKeyboardParentContainer",
      root_window);
  SetUsesScreenCoordinates(virtual_keyboard_parent_container);

#if defined(OS_CHROMEOS)
  aura::Window* mouse_cursor_container = CreateContainer(
      kShellWindowId_MouseCursorContainer,
      "MouseCursorContainer",
      root_window);
  SetUsesScreenCoordinates(mouse_cursor_container);
#endif

  CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
                  "PowerButtonAnimationContainer", root_window);
}

void RootWindowController::EnableTouchHudProjection() {
  if (touch_hud_projection_)
    return;
  set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
}

void RootWindowController::DisableTouchHudProjection() {
  if (!touch_hud_projection_)
    return;
  touch_hud_projection_->Remove();
}

void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
  shelf_->shelf_layout_manager()->UpdateVisibilityState();
}

void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
  if (enabled)
    EnableTouchHudProjection();
  else
    DisableTouchHudProjection();
}

RootWindowController* GetRootWindowController(
    const aura::Window* root_window) {
  return root_window ? GetRootWindowSettings(root_window)->controller : NULL;
}

}  // namespace ash
