// 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_output_protection.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/non_client_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/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/pointer_watcher_adapter.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_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/cursor_manager_chromeos.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/non_client_frame_controller.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/ws/gpu_interface_provider.h"
#include "services/ws/window_service.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.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/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/ozone/public/ozone_platform.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/mus/window_manager_frame_values.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);
  MessageCenterController::RegisterProfilePrefs(registry);
  NightLightController::RegisterProfilePrefs(registry);
  PaletteTray::RegisterProfilePrefs(registry);
  PaletteWelcomeBubble::RegisterProfilePrefs(registry);
  ShelfController::RegisterProfilePrefs(registry);
  TouchDevicesController::RegisterProfilePrefs(registry);
  CapsLockNotificationController::RegisterProfilePrefs(registry, for_test);
}

}  // namespace

// static
Shell* Shell::instance_ = nullptr;

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

// static
Shell* Shell::CreateInstance(ShellInitParams init_params) {
  CHECK(!instance_);
  instance_ = new Shell(std::move(init_params.delegate), init_params.connector);
  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));
  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.
  for (aura::Window* root : Shell::GetAllRootWindows()) {
    for (int modal_window_id : kSystemModalContainerIds) {
      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
bool Shell::HasRemoteClient(aura::Window* window) {
  return ws::WindowService::HasRemoteClient(window);
}

// static
Config Shell::GetAshConfig() {
  return Config::CLASSIC;
}

// static
void Shell::RegisterLocalStatePrefs(PrefRegistrySimple* registry,
                                    bool for_test) {
  PaletteTray::RegisterLocalStatePrefs(registry);
  WallpaperController::RegisterLocalStatePrefs(registry);
  BluetoothPowerController::RegisterLocalStatePrefs(registry);
  DetachableBaseHandler::RegisterPrefs(registry);
  // 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), aura_env_);
}

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

views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView(
    views::Widget* widget) {
  // Use translucent-style window frames for dialogs.
  return new NonClientFrameViewAsh(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): The keyboard UI uses a WebContents that is
  // created by chrome code but parented to an ash-created container window.
  // See ChromeKeyboardUI and keyboard::KeyboardController. This needs to be
  // fixed for both SingleProcessMash and MultiProcessMash.
  if (::features::IsUsingWindowService())
    return;

  auto keyboard_ui = shell_delegate_->CreateKeyboardUI();
  DCHECK(keyboard_ui);
  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() {
  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::ShowContextMenu(const gfx::Point& location_in_screen,
                            ui::MenuSourceType source_type) {
  // Bail with no active user session, in the lock screen, or in app/kiosk mode.
  if (session_controller_->NumberOfLoggedInUsers() < 1 ||
      session_controller_->IsScreenLocked() ||
      session_controller_->IsRunningInAppMode()) {
    return;
  }

  aura::Window* root = wm::GetRootWindowAt(location_in_screen);
  RootWindowController::ForWindow(root)->ShowContextMenu(location_in_screen,
                                                         source_type);
}

void Shell::AddPointerWatcher(views::PointerWatcher* watcher,
                              views::PointerWatcherEventTypes events) {
  pointer_watcher_adapter_->AddPointerWatcher(watcher, events);
}

void Shell::RemovePointerWatcher(views::PointerWatcher* watcher) {
  pointer_watcher_adapter_->RemovePointerWatcher(watcher);
}

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::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,
             service_manager::Connector* connector)
    : owned_aura_env_(::features::IsSingleProcessMash()
                          ? aura::Env::CreateLocalInstanceForInProcess()
                          : nullptr),
      aura_env_(owned_aura_env_.get() ? owned_aura_env_.get()
                                      : aura::Env::GetInstance()),
      ash_display_controller_(std::make_unique<AshDisplayController>()),
      brightness_control_delegate_(
          std::make_unique<system::BrightnessControllerChromeos>()),
      cast_config_(std::make_unique<CastConfigController>()),
      connector_(connector),
      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>(connector)),
      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_(std::make_unique<display::DisplayConfigurator>()),
      display_output_protection_(std::make_unique<DisplayOutputProtection>(
          display_configurator_.get())),
      native_cursor_manager_(nullptr),
      weak_factory_(this) {
  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");

  // 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 |assistant_controller_| earlier than |tablet_mode_controller_| so
  // that the former will destroy the Assistant view hierarchy which has a
  // dependency on the latter.
  if (chromeos::switches::IsAssistantEnabled())
    assistant_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();

  // Stop dispatching events (e.g. synthesized mouse exits from window close).
  // https://crbug.com/874156
  for (RootWindowController* rwc : GetAllRootWindowControllers())
    rwc->GetHost()->dispatcher()->Shutdown();

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

  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();

  pointer_watcher_adapter_.reset();

  // Stop observing window activation changes before closing all windows.
  focus_controller_->RemoveObserver(this);

  // 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.
  window_tree_host_manager_->Shutdown();

  // Depends on |focus_controller_|, so must be destroyed before.
  window_tree_host_manager_.reset();
  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();

  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<ws::GpuInterfaceProvider> gpu_interface_provider) {
  if (::features::IsSingleProcessMash()) {
    // In SingleProcessMash mode ScreenMus is not created, which means Ash needs
    // to set the WindowManagerFrameValues.
    views::WindowManagerFrameValues frame_values;
    frame_values.normal_insets = frame_values.maximized_insets =
        NonClientFrameController::GetPreferredClientAreaInsets();
    frame_values.max_title_bar_button_width =
        NonClientFrameController::GetMaxTitleBarButtonWidth();
    views::WindowManagerFrameValues::SetInstance(frame_values);
  }

  // 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 (connector_ && base::FeatureList::IsEnabled(
                        chromeos::features::kEnableUnifiedMultiDeviceSetup)) {
    multidevice_notification_presenter_ =
        std::make_unique<MultiDeviceNotificationPresenter>(
            message_center::MessageCenter::Get(), connector_);
  }

  // Connector can be null in tests.
  if (connector_) {
    // 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(
        connector_, std::move(pref_registry),
        base::Bind(&Shell::OnLocalStatePrefServiceInitialized,
                   weak_factory_.GetWeakPtr()),
        prefs::mojom::kLocalStateServiceName);
  }

  tablet_mode_controller_ = std::make_unique<TabletModeController>();

  accessibility_focus_ring_controller_ =
      std::make_unique<AccessibilityFocusRingController>();
  accessibility_delegate_.reset(shell_delegate_->CreateAccessibilityDelegate());
  accessibility_controller_ = std::make_unique<AccessibilityController>();
  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>();

  immersive_handler_factory_ = std::make_unique<ImmersiveHandlerFactoryAsh>();

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

  native_cursor_manager_ = new NativeCursorManagerAshClassic;
  cursor_manager_ =
      std::make_unique<CursorManager>(base::WrapUnique(native_cursor_manager_));

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

  // This will initialize aura::Env which requires |display_manager_| to
  // be initialized first.
  if (context_factory)
    aura_env_->set_context_factory(context_factory);
  if (context_factory_private)
    aura_env_->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_ =
      std::make_unique<::wm::WindowModalityController>(this, aura_env_);

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

  env_filter_ = std::make_unique<::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);

  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>();

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

  accelerator_controller_ = std::make_unique<AcceleratorController>(nullptr);
  voice_interaction_controller_ =
      std::make_unique<VoiceInteractionController>();

  window_service_owner_ =
      std::make_unique<WindowServiceOwner>(std::move(gpu_interface_provider));

  // |app_list_controller_| is put after |tablet_mode_controller_| as the former
  // uses the latter in constructor.
  app_list_controller_ = std::make_unique<AppListControllerImpl>(
      window_service_owner_->window_service());
  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>();

  system_gesture_filter_ = std::make_unique<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());

  if (::features::IsUsingWindowService())
    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());

  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));
  aura_env_->context_factory_private()
      ->GetHostFrameSinkManager()
      ->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).
  pointer_watcher_adapter_ = std::make_unique<PointerWatcherAdapter>();

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

  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(),
      std::make_unique<display::DefaultTouchTransformSetter>());

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

  // Needs to be created after InitDisplays() since it may cause the virtual
  // keyboard to be deployed.
  virtual_keyboard_controller_ = std::make_unique<VirtualKeyboardController>();

  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();

  // |connector_| is null in unit tests.
  if (connector_ &&
      base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowTaps)) {
    // The show taps feature is a separate mojo app.
    // TODO(jamescook): Make this work in ash_shell_with_content.
    connector_->StartService(tap_visualizer::mojom::kServiceName);
  }

  if (!::features::IsMultiProcessMash()) {
    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() {
  bool display_initialized = display_manager_->InitFromCommandLine();

  display_configuration_controller_ =
      std::make_unique<DisplayConfigurationController>(
          display_manager_.get(), window_tree_host_manager_.get());
  display_configurator_->Init(
      ui::OzonePlatform::GetInstance()->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 (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();

  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_;
}

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;
    }
  }
}

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
