// 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 <string>
#include <utility>

#include "ash/accelerators/accelerator_controller.h"
#include "ash/accelerators/accelerator_delegate.h"
#include "ash/accelerators/ash_focus_manager_factory.h"
#include "ash/accelerators/magnifier_key_scroller.h"
#include "ash/accelerators/spoken_feedback_toggler.h"
#include "ash/accessibility/accessibility_controller.h"
#include "ash/accessibility/accessibility_delegate.h"
#include "ash/accessibility/accessibility_focus_ring_controller.h"
#include "ash/accessibility/key_accessibility_enabler.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/assistant/assistant_controller.h"
#include "ash/autoclick/autoclick_controller.h"
#include "ash/cast_config_controller.h"
#include "ash/client_image_registry.h"
#include "ash/components/tap_visualizer/public/mojom/constants.mojom.h"
#include "ash/dbus/ash_dbus_services.h"
#include "ash/detachable_base/detachable_base_handler.h"
#include "ash/detachable_base/detachable_base_notification_controller.h"
#include "ash/display/ash_display_controller.h"
#include "ash/display/cros_display_config.h"
#include "ash/display/cursor_window_controller.h"
#include "ash/display/display_color_manager.h"
#include "ash/display/display_configuration_controller.h"
#include "ash/display/display_configuration_observer.h"
#include "ash/display/display_error_observer.h"
#include "ash/display/display_prefs.h"
#include "ash/display/display_shutdown_observer.h"
#include "ash/display/event_transformation_handler.h"
#include "ash/display/mouse_cursor_event_filter.h"
#include "ash/display/persistent_window_controller.h"
#include "ash/display/projecting_observer.h"
#include "ash/display/resolution_notification_controller.h"
#include "ash/display/screen_ash.h"
#include "ash/display/screen_orientation_controller.h"
#include "ash/display/screen_position_controller.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/drag_drop/drag_drop_controller.h"
#include "ash/events/event_rewriter_controller.h"
#include "ash/first_run/first_run_helper.h"
#include "ash/focus_cycler.h"
#include "ash/frame/custom_frame_view_ash.h"
#include "ash/high_contrast/high_contrast_controller.h"
#include "ash/highlighter/highlighter_controller.h"
#include "ash/host/ash_window_tree_host_init_params.h"
#include "ash/ime/ime_controller.h"
#include "ash/ime/ime_focus_handler.h"
#include "ash/keyboard/keyboard_ui.h"
#include "ash/keyboard/virtual_keyboard_controller.h"
#include "ash/laser/laser_pointer_controller.h"
#include "ash/login/login_screen_controller.h"
#include "ash/login_status.h"
#include "ash/magnifier/docked_magnifier_controller.h"
#include "ash/magnifier/magnification_controller.h"
#include "ash/magnifier/partial_magnification_controller.h"
#include "ash/media_controller.h"
#include "ash/message_center/message_center_controller.h"
#include "ash/metrics/time_to_first_present_recorder.h"
#include "ash/multi_device_setup/multi_device_notification_presenter.h"
#include "ash/new_window_controller.h"
#include "ash/note_taking_controller.h"
#include "ash/policy/policy_recommendation_restorer.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_switches.h"
#include "ash/public/cpp/config.h"
#include "ash/public/cpp/shelf_model.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h"
#include "ash/screenshot_delegate.h"
#include "ash/session/session_controller.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_controller.h"
#include "ash/shelf/shelf_window_watcher.h"
#include "ash/shell_delegate.h"
#include "ash/shell_init_params.h"
#include "ash/shell_observer.h"
#include "ash/shell_port.h"
#include "ash/shell_port_classic.h"
#include "ash/shell_state.h"
#include "ash/shutdown_controller.h"
#include "ash/sticky_keys/sticky_keys_controller.h"
#include "ash/system/audio/display_speaker_controller.h"
#include "ash/system/bluetooth/bluetooth_notification_controller.h"
#include "ash/system/bluetooth/bluetooth_power_controller.h"
#include "ash/system/bluetooth/tray_bluetooth_helper.h"
#include "ash/system/brightness/brightness_controller_chromeos.h"
#include "ash/system/brightness_control_delegate.h"
#include "ash/system/caps_lock_notification_controller.h"
#include "ash/system/keyboard_brightness/keyboard_brightness_controller.h"
#include "ash/system/keyboard_brightness_control_delegate.h"
#include "ash/system/locale/locale_notification_controller.h"
#include "ash/system/model/system_tray_model.h"
#include "ash/system/network/sms_observer.h"
#include "ash/system/network/vpn_list.h"
#include "ash/system/night_light/night_light_controller.h"
#include "ash/system/palette/palette_tray.h"
#include "ash/system/palette/palette_welcome_bubble.h"
#include "ash/system/power/backlights_forced_off_setter.h"
#include "ash/system/power/peripheral_battery_notifier.h"
#include "ash/system/power/power_button_controller.h"
#include "ash/system/power/power_event_observer.h"
#include "ash/system/power/power_prefs.h"
#include "ash/system/power/power_status.h"
#include "ash/system/power/video_activity_notifier.h"
#include "ash/system/screen_layout_observer.h"
#include "ash/system/screen_security/screen_switch_check_controller.h"
#include "ash/system/session/logout_button_tray.h"
#include "ash/system/session/logout_confirmation_controller.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/system_notification_controller.h"
#include "ash/system/toast/toast_manager.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/touch/ash_touch_transform_controller.h"
#include "ash/touch/touch_devices_controller.h"
#include "ash/tray_action/tray_action.h"
#include "ash/utility/screenshot_controller.h"
#include "ash/voice_interaction/voice_interaction_controller.h"
#include "ash/wallpaper/wallpaper_controller.h"
#include "ash/wayland/wayland_server_controller.h"
#include "ash/wm/ash_focus_rules.h"
#include "ash/wm/container_finder.h"
#include "ash/wm/event_client_impl.h"
#include "ash/wm/immersive_context_ash.h"
#include "ash/wm/immersive_handler_factory_ash.h"
#include "ash/wm/lock_state_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/native_cursor_manager_ash_classic.h"
#include "ash/wm/overlay_event_filter.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/resize_shadow_controller.h"
#include "ash/wm/root_window_finder.h"
#include "ash/wm/screen_pinning_controller.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/system_gesture_event_filter.h"
#include "ash/wm/system_modal_container_event_filter.h"
#include "ash/wm/system_modal_container_layout_manager.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_window_manager.h"
#include "ash/wm/toplevel_window_event_handler.h"
#include "ash/wm/video_detector.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_cycle_controller.h"
#include "ash/wm/window_positioner.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_shadow_controller_delegate.h"
#include "ash/wm/workspace_controller.h"
#include "ash/ws/window_service_owner.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/sys_info.h"
#include "base/trace_event/trace_event.h"
#include "chromeos/chromeos_features.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_policy_controller.h"
#include "chromeos/system/devicemode.h"
#include "components/exo/file_helper.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "mash/public/mojom/launchable.mojom.h"
#include "services/preferences/public/cpp/pref_service_factory.h"
#include "services/preferences/public/mojom/preferences.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/ws2/gpu_interface_provider.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/user_activity_forwarder.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/chromeos/user_activity_power_manager_notifier.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/display/display.h"
#include "ui/display/manager/default_touch_transform_setter.h"
#include "ui/display/manager/display_change_observer.h"
#include "ui/display/manager/display_configurator.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/touch_transform_setter.h"
#include "ui/display/mojo/dev_display_controller.mojom.h"
#include "ui/display/screen.h"
#include "ui/display/types/native_display_delegate.h"
#include "ui/events/event_target_iterator.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_switches.h"
#include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/views/corewm/tooltip_aura.h"
#include "ui/views/corewm/tooltip_controller.h"
#include "ui/views/focus/focus_manager_factory.h"
#include "ui/views/widget/native_widget_aura.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/accelerator_filter.h"
#include "ui/wm/core/compound_event_filter.h"
#include "ui/wm/core/focus_controller.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/visibility_controller.h"
#include "ui/wm/core/window_modality_controller.h"

namespace ash {

namespace {

using aura::Window;
using views::Widget;

bool g_is_browser_process_with_mash = false;

// A Corewm VisibilityController subclass that calls the Ash animation routine
// so we can pick up our extended animations. See ash/wm/window_animations.h.
class AshVisibilityController : public ::wm::VisibilityController {
 public:
  AshVisibilityController() = default;
  ~AshVisibilityController() override = default;

 private:
  // Overridden from ::wm::VisibilityController:
  bool CallAnimateOnChildWindowVisibilityChanged(aura::Window* window,
                                                 bool visible) override {
    return AnimateOnChildWindowVisibilityChanged(window, visible);
  }

  DISALLOW_COPY_AND_ASSIGN(AshVisibilityController);
};

// Registers prefs whose default values are same in user and signin prefs.
void RegisterProfilePrefs(PrefRegistrySimple* registry, bool for_test) {
  AccessibilityController::RegisterProfilePrefs(registry, for_test);
  BluetoothPowerController::RegisterProfilePrefs(registry);
  DockedMagnifierController::RegisterProfilePrefs(registry, for_test);
  LoginScreenController::RegisterProfilePrefs(registry, for_test);
  LogoutButtonTray::RegisterProfilePrefs(registry);
  NightLightController::RegisterProfilePrefs(registry);
  PaletteTray::RegisterProfilePrefs(registry);
  PaletteWelcomeBubble::RegisterProfilePrefs(registry);
  ShelfController::RegisterProfilePrefs(registry);
  TouchDevicesController::RegisterProfilePrefs(registry, for_test);
  CapsLockNotificationController::RegisterProfilePrefs(registry, for_test);
}

}  // namespace

// static
Shell* Shell::instance_ = nullptr;
// static
aura::WindowTreeClient* Shell::window_tree_client_ = nullptr;
// static
aura::WindowManagerClient* Shell::window_manager_client_ = nullptr;

////////////////////////////////////////////////////////////////////////////////
// Shell, public:

// static
Shell* Shell::CreateInstance(ShellInitParams init_params) {
  CHECK(!instance_);
  instance_ = new Shell(std::move(init_params.delegate),
                        std::move(init_params.shell_port));
  instance_->Init(
      init_params.context_factory, init_params.context_factory_private,
      std::move(init_params.initial_display_prefs),
      std::move(init_params.gpu_interface_provider), init_params.connector);
  return instance_;
}

// static
Shell* Shell::Get() {
  CHECK(!g_is_browser_process_with_mash)  // Implies null |instance_|.
      << "Ash is running in its own process so Shell::Get() will return null. "
         "The browser process must use the mojo interfaces in //ash/public to "
         "access ash. See ash/README.md for details.";
  CHECK(instance_);
  return instance_;
}

// static
bool Shell::HasInstance() {
  return !!instance_;
}

// static
void Shell::DeleteInstance() {
  delete instance_;
}

// static
RootWindowController* Shell::GetPrimaryRootWindowController() {
  CHECK(HasInstance());
  return RootWindowController::ForWindow(GetPrimaryRootWindow());
}

// static
Shell::RootWindowControllerList Shell::GetAllRootWindowControllers() {
  CHECK(HasInstance());
  RootWindowControllerList root_window_controllers;
  for (aura::Window* root : GetAllRootWindows())
    root_window_controllers.push_back(RootWindowController::ForWindow(root));
  return root_window_controllers;
}

// static
RootWindowController* Shell::GetRootWindowControllerWithDisplayId(
    int64_t display_id) {
  CHECK(HasInstance());
  aura::Window* root = GetRootWindowForDisplayId(display_id);
  return root ? RootWindowController::ForWindow(root) : nullptr;
}

// static
aura::Window* Shell::GetRootWindowForDisplayId(int64_t display_id) {
  CHECK(HasInstance());
  return instance_->window_tree_host_manager_->GetRootWindowForDisplayId(
      display_id);
}

// static
aura::Window* Shell::GetPrimaryRootWindow() {
  CHECK(HasInstance());
  return instance_->window_tree_host_manager_->GetPrimaryRootWindow();
}

// static
aura::Window* Shell::GetRootWindowForNewWindows() {
  return Shell::Get()->shell_state_->GetRootWindowForNewWindows();
}

// static
aura::Window::Windows Shell::GetAllRootWindows() {
  CHECK(HasInstance());
  return instance_->window_tree_host_manager_->GetAllRootWindows();
}

// static
aura::Window* Shell::GetContainer(aura::Window* root_window, int container_id) {
  return root_window->GetChildById(container_id);
}

// static
const aura::Window* Shell::GetContainer(const aura::Window* root_window,
                                        int container_id) {
  return root_window->GetChildById(container_id);
}

// static
int Shell::GetOpenSystemModalWindowContainerId() {
  // The test boolean is not static to avoid leaking state between tests.
  if (Get()->simulate_modal_window_open_for_test_)
    return kShellWindowId_SystemModalContainer;

  // Traverse all system modal containers, and find its direct child window
  // with "SystemModal" setting, and visible.
  // Note: LockSystemModalContainer is more restrictive, so make it preferable
  // to SystemModalCotainer.
  constexpr int modal_window_ids[] = {kShellWindowId_LockSystemModalContainer,
                                      kShellWindowId_SystemModalContainer};
  for (aura::Window* root : Shell::GetAllRootWindows()) {
    for (int modal_window_id : modal_window_ids) {
      aura::Window* system_modal = root->GetChildById(modal_window_id);
      if (!system_modal)
        continue;
      for (const aura::Window* child : system_modal->children()) {
        if (child->GetProperty(aura::client::kModalKey) ==
                ui::MODAL_TYPE_SYSTEM &&
            child->layer()->GetTargetVisibility()) {
          return modal_window_id;
        }
      }
    }
  }
  return -1;
}

// static
bool Shell::IsSystemModalWindowOpen() {
  return GetOpenSystemModalWindowContainerId() >= 0;
}

// static
Config Shell::GetAshConfig() {
  return Get()->shell_port_->GetAshConfig();
}

// static
bool Shell::ShouldUseIMEService() {
  return Shell::GetAshConfig() == Config::MASH ||
         base::FeatureList::IsEnabled(::features::kOopAsh);
}

// static
void Shell::RegisterLocalStatePrefs(PrefRegistrySimple* registry,
                                    bool for_test) {
  PaletteTray::RegisterLocalStatePrefs(registry);
  WallpaperController::RegisterLocalStatePrefs(registry);
  BluetoothPowerController::RegisterLocalStatePrefs(registry);
  DetachableBaseHandler::RegisterPrefs(registry);
  TouchDevicesController::RegisterLocalStatePrefs(registry, for_test);
  // Note: DisplayPrefs are registered in chrome in AshShellInit::RegisterPrefs
  // (see comment there for details).
  if (for_test)
    DisplayPrefs::RegisterLocalStatePrefs(registry);
  else
    DisplayPrefs::RegisterForeignPrefs(registry);
}

// static
void Shell::RegisterSigninProfilePrefs(PrefRegistrySimple* registry,
                                       bool for_test) {
  RegisterProfilePrefs(registry, for_test);
  PowerPrefs::RegisterSigninProfilePrefs(registry, for_test);
}

// static
void Shell::RegisterUserProfilePrefs(PrefRegistrySimple* registry,
                                     bool for_test) {
  RegisterProfilePrefs(registry, for_test);
  PowerPrefs::RegisterUserProfilePrefs(registry, for_test);
}

void Shell::InitWaylandServer(std::unique_ptr<exo::FileHelper> file_helper) {
  wayland_server_controller_ =
      WaylandServerController::CreateIfNecessary(std::move(file_helper));
}

void Shell::DestroyWaylandServer() {
  wayland_server_controller_.reset();
}

views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView(
    views::Widget* widget) {
  // Use translucent-style window frames for dialogs.
  return new CustomFrameViewAsh(widget);
}

void Shell::SetDisplayWorkAreaInsets(Window* contains,
                                     const gfx::Insets& insets) {
  window_tree_host_manager_->UpdateWorkAreaOfDisplayNearestWindow(contains,
                                                                  insets);
}

void Shell::OnCastingSessionStartedOrStopped(bool started) {
  for (auto& observer : shell_observers_)
    observer.OnCastingSessionStartedOrStopped(started);
}

void Shell::OnRootWindowAdded(aura::Window* root_window) {
  for (auto& observer : shell_observers_)
    observer.OnRootWindowAdded(root_window);
}

void Shell::OnDictationStarted() {
  for (auto& observer : shell_observers_)
    observer.OnDictationStarted();
}

void Shell::OnDictationEnded() {
  for (auto& observer : shell_observers_)
    observer.OnDictationEnded();
}

void Shell::EnableKeyboard() {
  if (!keyboard::IsKeyboardEnabled())
    return;

  if (keyboard_controller_->enabled()) {
    // Disable and re-enable the keyboard, as some callers expect the keyboard
    // to be reloaded.
    // TODO(https://crbug.com/731537): Add a separate function for reloading the
    // keyboard.
    for (auto* const controller : GetAllRootWindowControllers())
      controller->DeactivateKeyboard(keyboard_controller_.get());
  }

  // TODO(crbug.com/646565): ShellDelegateMash does not support keyboard ui yet.
  auto keyboard_ui = shell_delegate_->CreateKeyboardUI();
  if (!keyboard_ui && !::features::IsAshInBrowserProcess())
    return;

  keyboard_controller_->EnableKeyboard(std::move(keyboard_ui),
                                       virtual_keyboard_controller_.get());
  for (auto& observer : shell_observers_)
    observer.OnKeyboardControllerCreated();
  GetPrimaryRootWindowController()->ActivateKeyboard(
      keyboard_controller_.get());
}

void Shell::DisableKeyboard() {
  // TODO(jamescook): Move keyboard create and hide into ShellPort.
  keyboard_ui_->Hide();
  if (keyboard_controller_->enabled()) {
    for (auto* const controller : GetAllRootWindowControllers())
      controller->DeactivateKeyboard(keyboard_controller_.get());
  }

  keyboard_controller_->DisableKeyboard();
}

bool Shell::ShouldSaveDisplaySettings() {
  return !(
      screen_orientation_controller_->ignore_display_configuration_updates() ||
      resolution_notification_controller_->DoesNotificationTimeout());
}

DockedMagnifierController* Shell::docked_magnifier_controller() {
  DCHECK(features::IsDockedMagnifierEnabled());
  return docked_magnifier_controller_.get();
}

NightLightController* Shell::night_light_controller() {
  DCHECK(features::IsNightLightEnabled());
  return night_light_controller_.get();
}

ShelfModel* Shell::shelf_model() {
  return shelf_controller_->model();
}

::wm::ActivationClient* Shell::activation_client() {
  return focus_controller_.get();
}

void Shell::UpdateShelfVisibility() {
  for (aura::Window* root : GetAllRootWindows())
    Shelf::ForWindow(root)->UpdateVisibilityState();
}

NotificationTray* Shell::GetNotificationTray() {
  return GetPrimaryRootWindowController()
      ->GetStatusAreaWidget()
      ->notification_tray();
}

bool Shell::HasPrimaryStatusArea() {
  return !!GetPrimaryRootWindowController()->GetStatusAreaWidget();
}

SystemTray* Shell::GetPrimarySystemTray() {
  return GetPrimaryRootWindowController()->GetSystemTray();
}

void Shell::SetLargeCursorSizeInDip(int large_cursor_size_in_dip) {
  window_tree_host_manager_->cursor_window_controller()
      ->SetLargeCursorSizeInDip(large_cursor_size_in_dip);
}

void Shell::UpdateCursorCompositingEnabled() {
  SetCursorCompositingEnabled(
      window_tree_host_manager_->cursor_window_controller()
          ->ShouldEnableCursorCompositing());
}

void Shell::SetCursorCompositingEnabled(bool enabled) {
  if (GetAshConfig() != Config::MASH) {
    // TODO: needs to work in mash. http://crbug.com/705592.
    CursorWindowController* cursor_window_controller =
        window_tree_host_manager_->cursor_window_controller();

    if (cursor_window_controller->is_cursor_compositing_enabled() == enabled)
      return;
    cursor_window_controller->SetCursorCompositingEnabled(enabled);
    native_cursor_manager_->SetNativeCursorEnabled(!enabled);
  }
}

void Shell::DoInitialWorkspaceAnimation() {
  return GetPrimaryRootWindowController()
      ->workspace_controller()
      ->DoInitialAnimation();
}

bool Shell::IsSplitViewModeActive() const {
  return split_view_controller_.get() &&
         split_view_controller_->IsSplitViewModeActive();
}

void Shell::AddShellObserver(ShellObserver* observer) {
  shell_observers_.AddObserver(observer);
}

void Shell::RemoveShellObserver(ShellObserver* observer) {
  shell_observers_.RemoveObserver(observer);
}

void Shell::UpdateAfterLoginStatusChange(LoginStatus status) {
  for (auto* root_window_controller : GetAllRootWindowControllers())
    root_window_controller->UpdateAfterLoginStatusChange(status);
}

void Shell::NotifyOverviewModeStarting() {
  for (auto& observer : shell_observers_)
    observer.OnOverviewModeStarting();
}

void Shell::NotifyOverviewModeEnding() {
  for (auto& observer : shell_observers_)
    observer.OnOverviewModeEnding();
}

void Shell::NotifyOverviewModeEnded() {
  for (auto& observer : shell_observers_)
    observer.OnOverviewModeEnded();
}

void Shell::NotifySplitViewModeStarting() {
  for (auto& observer : shell_observers_)
    observer.OnSplitViewModeStarting();
}

void Shell::NotifySplitViewModeStarted() {
  for (auto& observer : shell_observers_)
    observer.OnSplitViewModeStarted();
}

void Shell::NotifySplitViewModeEnded() {
  for (auto& observer : shell_observers_)
    observer.OnSplitViewModeEnded();
}

void Shell::NotifyFullscreenStateChanged(bool is_fullscreen,
                                         aura::Window* root_window) {
  for (auto& observer : shell_observers_)
    observer.OnFullscreenStateChanged(is_fullscreen, root_window);
}

void Shell::NotifyPinnedStateChanged(aura::Window* pinned_window) {
  for (auto& observer : shell_observers_)
    observer.OnPinnedStateChanged(pinned_window);
}

void Shell::NotifyShelfCreatedForRootWindow(aura::Window* root_window) {
  for (auto& observer : shell_observers_)
    observer.OnShelfCreatedForRootWindow(root_window);
}

void Shell::NotifyShelfAlignmentChanged(aura::Window* root_window) {
  for (auto& observer : shell_observers_)
    observer.OnShelfAlignmentChanged(root_window);
}

void Shell::NotifyShelfAutoHideBehaviorChanged(aura::Window* root_window) {
  for (auto& observer : shell_observers_)
    observer.OnShelfAutoHideBehaviorChanged(root_window);
}

// static
void Shell::SetIsBrowserProcessWithMash() {
  g_is_browser_process_with_mash = true;
}

void Shell::NotifyAppListVisibilityChanged(bool visible,
                                           aura::Window* root_window) {
  for (auto& observer : shell_observers_)
    observer.OnAppListVisibilityChanged(visible, root_window);
}

////////////////////////////////////////////////////////////////////////////////
// Shell, private:

Shell::Shell(std::unique_ptr<ShellDelegate> shell_delegate,
             std::unique_ptr<ShellPort> shell_port)
    : shell_port_(std::move(shell_port)),
      ash_display_controller_(std::make_unique<AshDisplayController>()),
      brightness_control_delegate_(
          std::make_unique<system::BrightnessControllerChromeos>()),
      cast_config_(std::make_unique<CastConfigController>()),
      first_run_helper_(std::make_unique<FirstRunHelper>()),
      focus_cycler_(std::make_unique<FocusCycler>()),
      ime_controller_(std::make_unique<ImeController>()),
      immersive_context_(std::make_unique<ImmersiveContextAsh>()),
      keyboard_brightness_control_delegate_(
          std::make_unique<KeyboardBrightnessController>()),
      keyboard_controller_(std::make_unique<keyboard::KeyboardController>()),
      locale_notification_controller_(
          std::make_unique<LocaleNotificationController>()),
      login_screen_controller_(std::make_unique<LoginScreenController>()),
      media_controller_(std::make_unique<MediaController>()),
      new_window_controller_(std::make_unique<NewWindowController>()),
      session_controller_(std::make_unique<SessionController>(
          shell_delegate->GetShellConnector())),
      note_taking_controller_(std::make_unique<NoteTakingController>()),
      shell_delegate_(std::move(shell_delegate)),
      shell_state_(std::make_unique<ShellState>()),
      shutdown_controller_(std::make_unique<ShutdownController>()),
      system_tray_notifier_(std::make_unique<SystemTrayNotifier>()),
      vpn_list_(std::make_unique<VpnList>()),
      window_cycle_controller_(std::make_unique<WindowCycleController>()),
      window_selector_controller_(std::make_unique<WindowSelectorController>()),
      tray_bluetooth_helper_(std::make_unique<TrayBluetoothHelper>()),
      display_configurator_(new display::DisplayConfigurator()),
      native_cursor_manager_(nullptr),
      weak_factory_(this) {
  // TODO(sky): better refactor cash/mash dependencies. Perhaps put all cash
  // state on ShellPortClassic. http://crbug.com/671246.

  display_manager_.reset(ScreenAsh::CreateDisplayManager());
  window_tree_host_manager_ = std::make_unique<WindowTreeHostManager>();
  user_metrics_recorder_ = std::make_unique<UserMetricsRecorder>();

  PowerStatus::Initialize();

  session_controller_->AddObserver(this);
}

Shell::~Shell() {
  TRACE_EVENT0("shutdown", "ash::Shell::Destructor");

  const Config config = shell_port_->GetAshConfig();

  // Wayland depends upon some ash specific objects. Destroy it early on.
  wayland_server_controller_.reset();

  user_metrics_recorder_->OnShellShuttingDown();

  cros_display_config_.reset();
  display_configuration_observer_.reset();
  display_prefs_.reset();

  // Remove the focus from any window. This will prevent overhead and side
  // effects (e.g. crashes) from changing focus during shutdown.
  // See bug crbug.com/134502.
  aura::client::GetFocusClient(GetPrimaryRootWindow())->FocusWindow(nullptr);

  // Please keep in reverse order as in Init() because it's easy to miss one.
  if (window_modality_controller_)
    window_modality_controller_.reset();

  RemovePreTargetHandler(magnifier_key_scroll_handler_.get());
  magnifier_key_scroll_handler_.reset();

  RemovePreTargetHandler(speech_feedback_handler_.get());
  speech_feedback_handler_.reset();

  RemovePreTargetHandler(overlay_filter_.get());
  overlay_filter_.reset();

  RemovePreTargetHandler(accelerator_filter_.get());
  RemovePreTargetHandler(event_transformation_handler_.get());
  RemovePreTargetHandler(toplevel_window_event_handler_.get());
  RemovePostTargetHandler(toplevel_window_event_handler_.get());
  RemovePreTargetHandler(system_gesture_filter_.get());
  RemovePreTargetHandler(mouse_cursor_filter_.get());
  RemovePreTargetHandler(modality_filter_.get());
  RemovePreTargetHandler(tooltip_controller_.get());

  event_rewriter_controller_.reset();

  screen_orientation_controller_.reset();
  screen_layout_observer_.reset();

  // Destroy the virtual keyboard controller before the tablet mode controller
  // since the latters destructor triggers events that the former is listening
  // to but no longer cares about.
  virtual_keyboard_controller_.reset();

  // Depends on |tablet_mode_controller_|.
  shelf_controller_->Shutdown();

  // Destroy |app_list_controller_| early than |tablet_mode_controller_| since
  // the former may use the latter before destruction.
  app_list_controller_.reset();

  // Destroy tablet mode controller early on since it has some observers which
  // need to be removed.
  tablet_mode_controller_.reset();

  // Destroy the keyboard before closing the shelf, since it will invoke a shelf
  // layout.
  DisableKeyboard();

  toast_manager_.reset();

  tray_bluetooth_helper_.reset();

  // Accesses root window containers.
  logout_confirmation_controller_.reset();

  // Drag-and-drop must be canceled prior to close all windows.
  for (aura::Window* root : GetAllRootWindows())
    aura::client::SetDragDropClient(root, nullptr);
  drag_drop_controller_.reset();

  // Controllers who have WindowObserver added must be deleted
  // before |window_tree_host_manager_| is deleted.

  persistent_window_controller_.reset();

  // VideoActivityNotifier must be deleted before |video_detector_| is
  // deleted because it's observing video activity through
  // VideoDetector::Observer interface.
  video_activity_notifier_.reset();
  video_detector_.reset();
  high_contrast_controller_.reset();

  shadow_controller_.reset();
  resize_shadow_controller_.reset();

  // Has to happen before ~MruWindowTracker.
  window_cycle_controller_.reset();
  window_selector_controller_.reset();

  // |split_view_controller_| needs to be deleted after
  // |window_selector_controller_|.
  split_view_controller_.reset();

  // Close all widgets (including the shelf) and destroy all window containers.
  CloseAllRootWindowChildWindows();

  system_notification_controller_.reset();
  // Should be destroyed after Shelf and |system_notification_controller_|.
  system_tray_model_.reset();

  // MruWindowTracker must be destroyed after all windows have been deleted to
  // avoid a possible crash when Shell is destroyed from a non-normal shutdown
  // path. (crbug.com/485438).
  mru_window_tracker_.reset();

  // These need a valid Shell instance to clean up properly, so explicitly
  // delete them before invalidating the instance.
  // Alphabetical. TODO(oshima): sort.
  assistant_controller_.reset();
  magnification_controller_.reset();
  tooltip_controller_.reset();
  event_client_.reset();
  toplevel_window_event_handler_.reset();
  visibility_controller_.reset();
  power_prefs_.reset();

  tray_action_.reset();

  power_button_controller_.reset();
  lock_state_controller_.reset();
  backlights_forced_off_setter_.reset();

  screen_pinning_controller_.reset();

  multidevice_notification_presenter_.reset();
  resolution_notification_controller_.reset();
  screenshot_controller_.reset();
  mouse_cursor_filter_.reset();
  modality_filter_.reset();

  touch_transformer_controller_.reset();
  laser_pointer_controller_.reset();
  partial_magnification_controller_.reset();
  highlighter_controller_.reset();
  voice_interaction_controller_.reset();
  key_accessibility_enabler_.reset();

  display_speaker_controller_.reset();
  screen_switch_check_controller_.reset();

  // This also deletes all RootWindows. Note that we invoke Shutdown() on
  // WindowTreeHostManager before resetting |window_tree_host_manager_|, since
  // destruction of its owned RootWindowControllers relies on the value.
  ScreenAsh::CreateScreenForShutdown();
  display_configuration_controller_.reset();

  // These members access Shell in their destructors.
  wallpaper_controller_.reset();
  accessibility_controller_.reset();
  accessibility_delegate_.reset();
  accessibility_focus_ring_controller_.reset();
  policy_recommendation_restorer_.reset();

  // Balances the Install() in Initialize().
  views::FocusManagerFactory::Install(nullptr);

  // ShelfWindowWatcher has window observers and a pointer to the shelf model.
  shelf_window_watcher_.reset();

  // Removes itself as an observer of |pref_service_|.
  shelf_controller_.reset();

  // NightLightController depends on the PrefService as well as the window tree
  // host manager, and must be destructed before them. crbug.com/724231.
  night_light_controller_ = nullptr;
  // Similarly for DockedMagnifierController.
  docked_magnifier_controller_ = nullptr;

  // May own windows and other objects that have indirect hooks into
  // WindowTreeHostManager.
  window_service_owner_.reset();

  // Must be released before |focus_controller_|.
  ime_focus_handler_.reset();

  shell_port_->Shutdown();
  window_tree_host_manager_->Shutdown();

  // Depends on |focus_controller_|, so must be destroyed before.
  window_tree_host_manager_.reset();
  focus_controller_->RemoveObserver(this);
  if (config != Config::CLASSIC &&
      window_tree_client_->focus_synchronizer()->active_focus_client() ==
          focus_controller_.get()) {
    window_tree_client_->focus_synchronizer()->SetSingletonFocusClient(nullptr);
  }
  focus_controller_.reset();
  screen_position_controller_.reset();

  display_color_manager_.reset();
  projecting_observer_.reset();

  if (display_change_observer_)
    display_configurator_->RemoveObserver(display_change_observer_.get());
  if (display_error_observer_)
    display_configurator_->RemoveObserver(display_error_observer_.get());
  display_change_observer_.reset();
  display_shutdown_observer_.reset();

  PowerStatus::Shutdown();
  // Depends on SessionController.
  power_event_observer_.reset();

  // Needs to happen right before |instance_| is reset.
  shell_port_.reset();
  session_controller_->RemoveObserver(this);
  // BluetoothPowerController depends on the PrefService and must be destructed
  // before it.
  bluetooth_power_controller_ = nullptr;
  // TouchDevicesController depends on the PrefService and must be destructed
  // before it.
  touch_devices_controller_ = nullptr;
  // DetachableBaseNotificationController depends on DetachableBaseHandler, and
  // has to be destructed before it.
  detachable_base_notification_controller_.reset();
  // DetachableBaseHandler depends on the PrefService and must be destructed
  // before it.
  detachable_base_handler_.reset();

  // Destroys the MessageCenter singleton, so must happen late.
  message_center_controller_.reset();

  local_state_.reset();
  shell_delegate_.reset();

  for (auto& observer : shell_observers_)
    observer.OnShellDestroyed();

  DCHECK(instance_ == this);
  instance_ = nullptr;
}

void Shell::Init(
    ui::ContextFactory* context_factory,
    ui::ContextFactoryPrivate* context_factory_private,
    std::unique_ptr<base::Value> initial_display_prefs,
    std::unique_ptr<ui::ws2::GpuInterfaceProvider> gpu_interface_provider,
    service_manager::Connector* connector) {
  const Config config = shell_port_->GetAshConfig();

  connector_ = connector;

  // This creates the MessageCenter object which is used by some other objects
  // initialized here, so it needs to come early.
  message_center_controller_ = std::make_unique<MessageCenterController>();

  // These controllers call Shell::Get() in their constructors, so they cannot
  // be in the member initialization list.
  touch_devices_controller_ = std::make_unique<TouchDevicesController>();
  bluetooth_power_controller_ = std::make_unique<BluetoothPowerController>();
  detachable_base_handler_ = std::make_unique<DetachableBaseHandler>(this);
  detachable_base_notification_controller_ =
      std::make_unique<DetachableBaseNotificationController>(
          detachable_base_handler_.get());
  display_speaker_controller_ = std::make_unique<DisplaySpeakerController>();
  policy_recommendation_restorer_ =
      std::make_unique<PolicyRecommendationRestorer>();
  screen_switch_check_controller_ =
      std::make_unique<ScreenSwitchCheckController>();
  // Connector can be null in tests.
  if (shell_delegate_->GetShellConnector() &&
      base::FeatureList::IsEnabled(
          chromeos::features::kEnableUnifiedMultiDeviceSetup)) {
    multidevice_notification_presenter_ =
        std::make_unique<MultiDeviceNotificationPresenter>(
            message_center::MessageCenter::Get(),
            shell_delegate_->GetShellConnector());
  }

  // Connector can be null in tests.
  if (shell_delegate_->GetShellConnector()) {
    // Connect to local state prefs now, but wait for an active user before
    // connecting to the profile pref service. The login screen has a temporary
    // user profile that is not associated with a real user.
    auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
    RegisterLocalStatePrefs(pref_registry.get(), false);
    prefs::ConnectToPrefService(
        shell_delegate_->GetShellConnector(), std::move(pref_registry),
        base::Bind(&Shell::OnLocalStatePrefServiceInitialized,
                   weak_factory_.GetWeakPtr()),
        prefs::mojom::kLocalStateServiceName);
  }

  // Some delegates access ShellPort during their construction. Create them here
  // instead of the ShellPort constructor.
  accessibility_focus_ring_controller_ =
      std::make_unique<AccessibilityFocusRingController>();
  accessibility_delegate_.reset(shell_delegate_->CreateAccessibilityDelegate());
  accessibility_controller_ = std::make_unique<AccessibilityController>(
      shell_delegate_->GetShellConnector());
  toast_manager_ = std::make_unique<ToastManager>();

  // Install the custom factory early on so that views::FocusManagers for Tray,
  // Shelf, and WallPaper could be created by the factory.
  views::FocusManagerFactory::Install(new AshFocusManagerFactory);

  wallpaper_controller_ = std::make_unique<WallpaperController>();

  // TODO(sky): move creation to ShellPort.
  if (config != Config::MASH)
    immersive_handler_factory_ = std::make_unique<ImmersiveHandlerFactoryAsh>();

  window_positioner_ = std::make_unique<WindowPositioner>();

  if (config == Config::CLASSIC) {
    native_cursor_manager_ = new NativeCursorManagerAshClassic;
    cursor_manager_ = std::make_unique<CursorManager>(
        base::WrapUnique(native_cursor_manager_));
  } else {
    // TODO(jamescook|estade): Cursor manager for Config::MASH. We might be able
    // to use most of the classic version after we switch to ws2.
  }

  shell_delegate_->PreInit();

  // In CLASSIC mode, |initial_display_prefs| contains the synchronously
  // loaded display pref values. Otherwise |initial_display_prefs| is null and
  // the pref values will be loaded once |local_state_| is available. (Any store
  // requests in the meanwhile will be queued).
  display_prefs_ =
      std::make_unique<DisplayPrefs>(std::move(initial_display_prefs));

  InitializeDisplayManager();

  if (config == Config::CLASSIC) {
    // This will initialize aura::Env which requires |display_manager_| to
    // be initialized first.
    if (context_factory)
      aura::Env::GetInstance()->set_context_factory(context_factory);
    if (context_factory_private) {
      aura::Env::GetInstance()->set_context_factory_private(
          context_factory_private);
    }
  }

  // Night Light depends on the display manager, the display color manager, and
  // aura::Env, so initialize it after all have been initialized.
  if (features::IsNightLightEnabled())
    night_light_controller_ = std::make_unique<NightLightController>();

  // The WindowModalityController needs to be at the front of the input event
  // pretarget handler list to ensure that it processes input events when modal
  // windows are active.
  window_modality_controller_.reset(new ::wm::WindowModalityController(this));

  event_rewriter_controller_ = std::make_unique<EventRewriterController>();

  env_filter_.reset(new ::wm::CompoundEventFilter);
  AddPreTargetHandler(env_filter_.get());

  // FocusController takes ownership of AshFocusRules.
  focus_controller_ =
      std::make_unique<::wm::FocusController>(new wm::AshFocusRules());
  focus_controller_->AddObserver(this);
  if (config != Config::CLASSIC) {
    window_tree_client_->focus_synchronizer()->SetSingletonFocusClient(
        focus_controller_.get());
  }

  screen_position_controller_.reset(new ScreenPositionController);

  window_tree_host_manager_->Start();
  AshWindowTreeHostInitParams ash_init_params;
  window_tree_host_manager_->CreatePrimaryHost(ash_init_params);

  time_to_first_present_recorder_ =
      std::make_unique<TimeToFirstPresentRecorder>(GetPrimaryRootWindow());

  shell_state_->SetRootWindowForNewWindows(GetPrimaryRootWindow());

  resolution_notification_controller_ =
      std::make_unique<ResolutionNotificationController>();

  if (cursor_manager_) {
    cursor_manager_->SetDisplay(
        display::Screen::GetScreen()->GetPrimaryDisplay());
  }

  accelerator_controller_ = shell_port_->CreateAcceleratorController();
  tablet_mode_controller_ = std::make_unique<TabletModeController>();

  // |app_list_controller_| is put after |tablet_mode_controller_| as the former
  // uses the latter in constructor.
  app_list_controller_ = std::make_unique<AppListControllerImpl>();
  shelf_controller_ = std::make_unique<ShelfController>();

  magnifier_key_scroll_handler_ = MagnifierKeyScroller::CreateHandler();
  AddPreTargetHandler(magnifier_key_scroll_handler_.get());
  speech_feedback_handler_ = SpokenFeedbackToggler::CreateHandler();
  AddPreTargetHandler(speech_feedback_handler_.get());

  // The order in which event filters are added is significant.

  // ui::UserActivityDetector passes events to observers, so let them get
  // rewritten first.
  user_activity_detector_.reset(new ui::UserActivityDetector);

  overlay_filter_.reset(new OverlayEventFilter);
  AddPreTargetHandler(overlay_filter_.get());

  accelerator_filter_.reset(new ::wm::AcceleratorFilter(
      std::unique_ptr<::wm::AcceleratorDelegate>(new AcceleratorDelegate),
      accelerator_controller_->accelerator_history()));
  AddPreTargetHandler(accelerator_filter_.get());

  event_transformation_handler_.reset(new EventTransformationHandler);
  AddPreTargetHandler(event_transformation_handler_.get());

  toplevel_window_event_handler_ =
      std::make_unique<ToplevelWindowEventHandler>();

  if (config != Config::MASH) {
    system_gesture_filter_.reset(new SystemGestureEventFilter);
    AddPreTargetHandler(system_gesture_filter_.get());
  }

  sticky_keys_controller_.reset(new StickyKeysController);
  screen_pinning_controller_ = std::make_unique<ScreenPinningController>();

  power_prefs_ = std::make_unique<PowerPrefs>(
      chromeos::PowerPolicyController::Get(),
      chromeos::DBusThreadManager::Get()->GetPowerManagerClient());

  backlights_forced_off_setter_ = std::make_unique<BacklightsForcedOffSetter>();

  tray_action_ =
      std::make_unique<TrayAction>(backlights_forced_off_setter_.get());

  lock_state_controller_ =
      std::make_unique<LockStateController>(shutdown_controller_.get());
  power_button_controller_ = std::make_unique<PowerButtonController>(
      backlights_forced_off_setter_.get());
  // Pass the initial display state to PowerButtonController.
  power_button_controller_->OnDisplayModeChanged(
      display_configurator_->cached_displays());

  // Forward user activity from the window server to |user_activity_detector_|.
  // The connector is unavailable in some tests.
  if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS &&
      shell_delegate_->GetShellConnector()) {
    ui::mojom::UserActivityMonitorPtr user_activity_monitor;
    shell_delegate_->GetShellConnector()->BindInterface(ui::mojom::kServiceName,
                                                        &user_activity_monitor);
    user_activity_forwarder_ = std::make_unique<aura::UserActivityForwarder>(
        std::move(user_activity_monitor), user_activity_detector_.get());
  }

  if (!::features::IsAshInBrowserProcess())
    client_image_registry_ = std::make_unique<ClientImageRegistry>();

  // In mash drag and drop is handled by mus.
  if (config != Config::MASH)
    drag_drop_controller_ = std::make_unique<DragDropController>();

  // |screenshot_controller_| needs to be created (and prepended as a
  // pre-target handler) at this point, because |mouse_cursor_filter_| needs to
  // process mouse events prior to screenshot session.
  // See http://crbug.com/459214
  screenshot_controller_ = std::make_unique<ScreenshotController>(
      shell_delegate_->CreateScreenshotDelegate());
  mouse_cursor_filter_ = std::make_unique<MouseCursorEventFilter>();
  AddPreTargetHandler(mouse_cursor_filter_.get(),
                      ui::EventTarget::Priority::kAccessibility);

  // Create Controllers that may need root window.
  // TODO(oshima): Move as many controllers before creating
  // RootWindowController as possible.
  visibility_controller_.reset(new AshVisibilityController);

  laser_pointer_controller_.reset(new LaserPointerController());
  partial_magnification_controller_.reset(new PartialMagnificationController());
  highlighter_controller_.reset(new HighlighterController());
  voice_interaction_controller_ =
      std::make_unique<VoiceInteractionController>();

  assistant_controller_ = chromeos::switches::IsAssistantEnabled()
                              ? std::make_unique<AssistantController>()
                              : nullptr;

  magnification_controller_ = std::make_unique<MagnificationController>();
  mru_window_tracker_ = std::make_unique<MruWindowTracker>();

  autoclick_controller_.reset(AutoclickController::CreateInstance());

  high_contrast_controller_.reset(new HighContrastController);

  if (features::IsDockedMagnifierEnabled()) {
    docked_magnifier_controller_ =
        std::make_unique<DockedMagnifierController>();
  }

  viz::mojom::VideoDetectorObserverPtr observer;
  video_detector_ =
      std::make_unique<VideoDetector>(mojo::MakeRequest(&observer));
  shell_port_->AddVideoDetectorObserver(std::move(observer));

  tooltip_controller_.reset(new views::corewm::TooltipController(
      std::unique_ptr<views::corewm::Tooltip>(new views::corewm::TooltipAura)));
  AddPreTargetHandler(tooltip_controller_.get());

  modality_filter_.reset(new SystemModalContainerEventFilter(this));
  AddPreTargetHandler(modality_filter_.get());

  event_client_.reset(new EventClientImpl);

  // Must occur after Shell has installed its early pre-target handlers (for
  // example, WindowModalityController).
  shell_port_->CreatePointerWatcherAdapter();

  resize_shadow_controller_.reset(new ResizeShadowController());
  shadow_controller_.reset(new ::wm::ShadowController(
      focus_controller_.get(), std::make_unique<WmShadowControllerDelegate>()));

  logout_confirmation_controller_ =
      std::make_unique<LogoutConfirmationController>();

  // May trigger initialization of the Bluetooth adapter.
  tray_bluetooth_helper_->Initialize();

  // Create AshTouchTransformController before
  // WindowTreeHostManager::InitDisplays()
  // since AshTouchTransformController listens on
  // WindowTreeHostManager::Observer::OnDisplaysInitialized().
  touch_transformer_controller_ = std::make_unique<AshTouchTransformController>(
      display_configurator_.get(), display_manager_.get(),
      shell_port_->CreateTouchTransformDelegate());

  keyboard_ui_ = shell_port_->CreateKeyboardUI();

  // |system_tray_model_| should be available before
  // |system_notification_controller_| is initialized and Shelf is created by
  // WindowTreeHostManager::InitHosts.
  system_tray_model_ = std::make_unique<SystemTrayModel>();
  system_notification_controller_ =
      std::make_unique<SystemNotificationController>();

  window_tree_host_manager_->InitHosts();
  shell_port_->OnHostsInitialized();

  // Needs to be created after InitDisplays() since it may cause the virtual
  // keyboard to be deployed.
  if (config != Config::MASH)
    virtual_keyboard_controller_.reset(new VirtualKeyboardController);

  if (cursor_manager_) {
    cursor_manager_->HideCursor();  // Hide the mouse cursor on startup.
    cursor_manager_->SetCursor(ui::CursorType::kPointer);
  }

  peripheral_battery_notifier_ = std::make_unique<PeripheralBatteryNotifier>();
  power_event_observer_.reset(new PowerEventObserver());
  user_activity_notifier_.reset(
      new ui::UserActivityPowerManagerNotifier(user_activity_detector_.get()));
  video_activity_notifier_.reset(
      new VideoActivityNotifier(video_detector_.get()));
  bluetooth_notification_controller_.reset(new BluetoothNotificationController);
  screen_orientation_controller_ =
      std::make_unique<ScreenOrientationController>();
  screen_layout_observer_.reset(new ScreenLayoutObserver());
  sms_observer_.reset(new SmsObserver());

  split_view_controller_.reset(new SplitViewController());

  key_accessibility_enabler_ = std::make_unique<KeyAccessibilityEnabler>();

  // The compositor thread and main message loop have to be running in
  // order to create mirror window. Run it after the main message loop
  // is started.
  display_manager_->CreateMirrorWindowAsyncIfAny();

  // The show taps feature can be implemented with a separate mojo app.
  // GetShellConnector() is null in unit tests.
  // TODO(jamescook): Make this work in ash_shell_with_content.
  if (shell_delegate_->GetShellConnector() &&
      base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowTaps) &&
      base::FeatureList::IsEnabled(features::kTapVisualizerApp)) {
    shell_delegate_->GetShellConnector()->StartService(
        tap_visualizer::mojom::kServiceName);
  }

  if (config != Config::MASH) {
    window_service_owner_ =
        std::make_unique<WindowServiceOwner>(std::move(gpu_interface_provider));
    if (!ShouldUseIMEService()) {
      ime_focus_handler_ = std::make_unique<ImeFocusHandler>(
          focus_controller(), window_tree_host_manager_->input_method());
    }
  }

  for (auto& observer : shell_observers_)
    observer.OnShellInitialized();

  user_metrics_recorder_->OnShellInitialized();

  // Initialize the D-Bus thread and services for ash.
  ash_dbus_services_ = std::make_unique<AshDBusServices>();
  // By this point ash shell should have initialized its D-Bus signal
  // listeners, so emit ash-initialized upstart signal to start Chrome OS tasks
  // that expect that ash is listening to D-Bus signals they emit. For example,
  // hammerd, which handles detachable base state, communicates the base state
  // purely by emitting D-Bus signals, and thus has to be run whenever ash is
  // started so ash (DetachableBaseHandler in particular) gets the proper view
  // of the current detachable base state.
  // TODO(stevenjb): Move this and other D-Bus dependencies to AshDBusServices.
  ash_dbus_services_->EmitAshInitialized();
}

void Shell::InitializeDisplayManager() {
  const Config config = shell_port_->GetAshConfig();
  bool display_initialized = display_manager_->InitFromCommandLine();

  if (!display_initialized && config != Config::CLASSIC) {
    // Run display configuration off device in mus mode.
    display_manager_->set_configure_displays(true);
    display_configurator_->set_configure_display(true);
  }
  display_configuration_controller_ =
      std::make_unique<DisplayConfigurationController>(
          display_manager_.get(), window_tree_host_manager_.get());
  display_configurator_->Init(shell_port_->CreateNativeDisplayDelegate(),
                              false);
  display_configuration_observer_ =
      std::make_unique<DisplayConfigurationObserver>();

  cros_display_config_ = std::make_unique<CrosDisplayConfig>();

  persistent_window_controller_ =
      std::make_unique<PersistentWindowController>();

  projecting_observer_ =
      std::make_unique<ProjectingObserver>(display_configurator_.get());

  if (!display_initialized) {
    if (config != Config::CLASSIC && !chromeos::IsRunningAsSystemCompositor()) {
      display::mojom::DevDisplayControllerPtr controller;
      shell_delegate_->GetShellConnector()->BindInterface(
          ui::mojom::kServiceName, &controller);
      display_manager_->SetDevDisplayController(std::move(controller));
    }

    if (config != Config::CLASSIC || chromeos::IsRunningAsSystemCompositor()) {
      display_change_observer_ =
          std::make_unique<display::DisplayChangeObserver>(
              display_configurator_.get(), display_manager_.get());

      display_shutdown_observer_ = std::make_unique<DisplayShutdownObserver>(
          display_configurator_.get());

      // Register |display_change_observer_| first so that the rest of
      // observer gets invoked after the root windows are configured.
      display_configurator_->AddObserver(display_change_observer_.get());
      display_error_observer_.reset(new DisplayErrorObserver());
      display_configurator_->AddObserver(display_error_observer_.get());
      display_configurator_->set_state_controller(
          display_change_observer_.get());
      display_configurator_->set_mirroring_controller(display_manager_.get());
      display_configurator_->ForceInitialConfigure();
      display_initialized = true;
    }
  }

  display_color_manager_ = std::make_unique<DisplayColorManager>(
      display_configurator_.get(), display::Screen::GetScreen());

  if (!display_initialized)
    display_manager_->InitDefaultDisplay();

  if (config == Config::CLASSIC)
    display_manager_->RefreshFontParams();
}

void Shell::InitRootWindow(aura::Window* root_window) {
  DCHECK(focus_controller_);
  DCHECK(visibility_controller_.get());

  aura::client::SetFocusClient(root_window, focus_controller_.get());
  ::wm::SetActivationClient(root_window, focus_controller_.get());
  root_window->AddPreTargetHandler(focus_controller_.get());
  aura::client::SetVisibilityClient(root_window, visibility_controller_.get());
  if (drag_drop_controller_) {
    DCHECK_NE(Config::MASH, GetAshConfig());
    aura::client::SetDragDropClient(root_window, drag_drop_controller_.get());
  } else {
    DCHECK_EQ(Config::MASH, GetAshConfig());
  }
  aura::client::SetScreenPositionClient(root_window,
                                        screen_position_controller_.get());
  aura::client::SetCursorClient(root_window, cursor_manager_.get());
  ::wm::SetTooltipClient(root_window, tooltip_controller_.get());
  aura::client::SetEventClient(root_window, event_client_.get());

  ::wm::SetWindowMoveClient(root_window, toplevel_window_event_handler_.get());
  root_window->AddPreTargetHandler(toplevel_window_event_handler_.get());
  root_window->AddPostTargetHandler(toplevel_window_event_handler_.get());
}

void Shell::CloseAllRootWindowChildWindows() {
  for (aura::Window* root : GetAllRootWindows()) {
    RootWindowController* controller = RootWindowController::ForWindow(root);
    if (controller) {
      controller->CloseChildWindows();
    } else {
      while (!root->children().empty()) {
        aura::Window* child = root->children()[0];
        delete child;
      }
    }
  }
}

bool Shell::CanWindowReceiveEvents(aura::Window* window) {
  RootWindowControllerList controllers = GetAllRootWindowControllers();
  for (RootWindowController* controller : controllers) {
    if (controller->CanWindowReceiveEvents(window))
      return true;
  }
  return false;
}

////////////////////////////////////////////////////////////////////////////////
// Shell, ui::EventTarget overrides:

bool Shell::CanAcceptEvent(const ui::Event& event) {
  return true;
}

ui::EventTarget* Shell::GetParentTarget() {
  return aura::Env::GetInstance();
}

std::unique_ptr<ui::EventTargetIterator> Shell::GetChildIterator() const {
  return std::unique_ptr<ui::EventTargetIterator>();
}

ui::EventTargeter* Shell::GetEventTargeter() {
  NOTREACHED();
  return nullptr;
}

void Shell::OnWindowActivated(
    ::wm::ActivationChangeObserver::ActivationReason reason,
    aura::Window* gained_active,
    aura::Window* lost_active) {
  if (!gained_active)
    return;

  shell_state_->SetRootWindowForNewWindows(gained_active->GetRootWindow());
}

void Shell::OnFirstSessionStarted() {
  // Enable magnifier scroll keys as there may be no mouse cursor in kiosk mode.
  MagnifierKeyScroller::SetEnabled(session_controller_->IsRunningInAppMode());

  // Enable long press action to toggle spoken feedback with hotrod remote
  // which can't handle shortcuts.
  SpokenFeedbackToggler::SetEnabled(session_controller_->IsRunningInAppMode());
}

void Shell::OnSessionStateChanged(session_manager::SessionState state) {
  // Initialize the |shelf_window_watcher_| when a session becomes active.
  // Shelf itself is initialized in RootWindowController.
  if (state == session_manager::SessionState::ACTIVE) {
    if (!shelf_window_watcher_) {
      shelf_window_watcher_ =
          std::make_unique<ShelfWindowWatcher>(shelf_model());
    }
  }

  // NOTE: keyboard::IsKeyboardEnabled() is false in mash, but may not be in
  // unit tests. crbug.com/646565.
  if (keyboard::IsKeyboardEnabled()) {
    switch (state) {
      case session_manager::SessionState::OOBE:
      case session_manager::SessionState::LOGIN_PRIMARY:
        // Ensure that the keyboard controller is activated for the primary
        // window.
        GetPrimaryRootWindowController()->ActivateKeyboard(
            keyboard_controller_.get());
        break;
      case session_manager::SessionState::LOGGED_IN_NOT_ACTIVE:
      case session_manager::SessionState::ACTIVE:
        // Reload the keyboard on user profile change to refresh keyboard
        // extensions with the new profile and ensure the extensions call the
        // proper IME. |LOGGED_IN_NOT_ACTIVE| is needed so that the virtual
        // keyboard works on supervised user creation, http://crbug.com/712873.
        // |ACTIVE| is also needed for guest user workflow.
        EnableKeyboard();
        break;
      default:
        break;
    }
  }

  shell_port_->UpdateSystemModalAndBlockingContainers();
}

void Shell::OnLoginStatusChanged(LoginStatus login_status) {
  UpdateAfterLoginStatusChange(login_status);
}

void Shell::OnLockStateChanged(bool locked) {
#ifndef NDEBUG
  // Make sure that there is no system modal in Lock layer when unlocked.
  if (!locked) {
    aura::Window::Windows containers = wm::GetContainersFromAllRootWindows(
        kShellWindowId_LockSystemModalContainer, GetPrimaryRootWindow());
    for (aura::Window* container : containers)
      DCHECK(container->children().empty());
  }
#endif
}

void Shell::OnLocalStatePrefServiceInitialized(
    std::unique_ptr<::PrefService> pref_service) {
  DCHECK(!local_state_);
  // |pref_service| is null if can't connect to Chrome (as happens when
  // running mash outside of chrome --enable-features=Mash and chrome isn't
  // built).
  if (!pref_service)
    return;

  local_state_ = std::move(pref_service);

  for (auto& observer : shell_observers_)
    observer.OnLocalStatePrefServiceInitialized(local_state_.get());
}

}  // namespace ash
