// 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_DEPRECATED ||
         base::FeatureList::IsEnabled(::features::kMash);
}

// 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_DEPRECATED) {
    // 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_DEPRECATED)
    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_DEPRECATED. 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_DEPRECATED) {
    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>();

  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_DEPRECATED)
    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_DEPRECATED) {
    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());
  aura::client::SetDragDropClient(root_window, drag_drop_controller_.get());
  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
