// Copyright 2015 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/window_manager.h"

#include <stdint.h>

#include <limits>
#include <memory>
#include <utility>

#include "ash/accelerators/accelerator_handler.h"
#include "ash/accelerators/accelerator_ids.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/drag_drop/drag_image_view.h"
#include "ash/event_matcher_util.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/cpp/window_state_type.h"
#include "ash/public/interfaces/window_actions.mojom.h"
#include "ash/root_window_controller.h"
#include "ash/root_window_settings.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/shell_delegate_mash.h"
#include "ash/shell_init_params.h"
#include "ash/shell_port_mash.h"
#include "ash/wm/ash_focus_rules.h"
#include "ash/wm/move_event_handler.h"
#include "ash/wm/non_client_frame_controller.h"
#include "ash/wm/property_util.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/top_level_window_factory.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_state.h"
#include "components/exo/file_helper.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/common/accelerator_util.h"
#include "services/ui/common/types.h"
#include "services/ui/public/cpp/input_devices/input_device_client.h"
#include "services/ui/public/cpp/property_type_converters.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "services/ui/public/interfaces/window_manager.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/window_parenting_client.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/capture_synchronizer.h"
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/window.h"
#include "ui/base/class_property.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display_observer.h"
#include "ui/events/mojo/event.mojom.h"
#include "ui/views/mus/pointer_watcher_event_router.h"
#include "ui/wm/core/capture_controller.h"
#include "ui/wm/core/window_animations.h"
#include "ui/wm/core/wm_state.h"
#include "ui/wm/public/activation_client.h"

namespace ash {

struct WindowManager::DragState {
  // An image representation of the contents of the current drag and drop
  // clipboard.
  std::unique_ptr<ash::DragImageView> view;

  // The cursor offset of the dragged item.
  gfx::Vector2d image_offset;
};

// TODO: need to register OSExchangeDataProviderMus. http://crbug.com/665077.
WindowManager::WindowManager(service_manager::Connector* connector,
                             bool show_primary_host_on_connect)
    : connector_(connector),
      show_primary_host_on_connect_(show_primary_host_on_connect),
      wm_state_(std::make_unique<::wm::WMState>()),
      property_converter_(std::make_unique<aura::PropertyConverter>()) {
  DCHECK(!features::IsAshInBrowserProcess());
  RegisterWindowProperties(property_converter_.get());
}

WindowManager::~WindowManager() {
  Shutdown();
  ash::Shell::set_window_tree_client(nullptr);
  ash::Shell::set_window_manager_client(nullptr);
}

void WindowManager::Init(
    std::unique_ptr<aura::WindowTreeClient> window_tree_client,
    std::unique_ptr<base::Value> initial_display_prefs) {
  input_device_client_ = std::make_unique<ui::InputDeviceClient>();

  // |connector_| can be nullptr in tests.
  if (connector_) {
    ui::mojom::InputDeviceServerPtr server;
    connector_->BindInterface(ui::mojom::kServiceName, &server);
    input_device_client_->Connect(std::move(server));
  }

  DCHECK(window_manager_client_);
  DCHECK(!window_tree_client_);
  window_tree_client_ = std::move(window_tree_client);

  DCHECK_EQ(nullptr, ash::Shell::window_tree_client());
  ash::Shell::set_window_tree_client(window_tree_client_.get());

  pointer_watcher_event_router_ =
      std::make_unique<views::PointerWatcherEventRouter>(
          window_tree_client_.get());

  // Notify PointerWatcherEventRouter and CaptureSynchronizer that the capture
  // client has been set.
  aura::client::CaptureClient* capture_client = wm_state_->capture_controller();
  pointer_watcher_event_router_->AttachToCaptureClient(capture_client);
  window_tree_client_->capture_synchronizer()->AttachToCaptureClient(
      capture_client);

  initial_display_prefs_ = std::move(initial_display_prefs);

  InitCursorOnKeyList();
}

bool WindowManager::GetNextAcceleratorNamespaceId(uint16_t* id) {
  if (accelerator_handlers_.size() == std::numeric_limits<uint16_t>::max())
    return false;
  while (accelerator_handlers_.count(next_accelerator_namespace_id_) > 0)
    ++next_accelerator_namespace_id_;
  *id = next_accelerator_namespace_id_;
  ++next_accelerator_namespace_id_;
  return true;
}

void WindowManager::AddAcceleratorHandler(uint16_t id_namespace,
                                          AcceleratorHandler* handler) {
  DCHECK_EQ(0u, accelerator_handlers_.count(id_namespace));
  accelerator_handlers_[id_namespace] = handler;
}

void WindowManager::RemoveAcceleratorHandler(uint16_t id_namespace) {
  accelerator_handlers_.erase(id_namespace);
}

display::mojom::DisplayController* WindowManager::GetDisplayController() {
  return display_controller_ ? display_controller_.get() : nullptr;
}

void WindowManager::CreateShell() {
  DCHECK(!created_shell_);
  created_shell_ = true;
  ShellInitParams init_params;
  init_params.shell_port = std::make_unique<ShellPortMash>(
      this, pointer_watcher_event_router_.get());
  init_params.delegate = shell_delegate_
                             ? std::move(shell_delegate_)
                             : std::make_unique<ShellDelegateMash>(connector_);
  init_params.initial_display_prefs = std::move(initial_display_prefs_);
  Shell::CreateInstance(std::move(init_params));
}

void WindowManager::InitCursorOnKeyList() {
  DCHECK(window_manager_client_);
  // In Mash, we build a list of keys and send them to the window
  // server. This controls which keys *don't* hide the cursors.

  // TODO(erg): This needs to also check the case of the accessibility
  // keyboard being shown, since clicking a key on the keyboard shouldn't
  // hide the cursor.
  std::vector<ui::mojom::EventMatcherPtr> cursor_key_list;
  cursor_key_list.push_back(BuildKeyReleaseMatcher());
  cursor_key_list.push_back(BuildAltMatcher());
  cursor_key_list.push_back(BuildControlMatcher());

  BuildKeyMatcherRange(ui::mojom::KeyboardCode::F1,
                       ui::mojom::KeyboardCode::F24, &cursor_key_list);
  BuildKeyMatcherRange(ui::mojom::KeyboardCode::BROWSER_BACK,
                       ui::mojom::KeyboardCode::MEDIA_LAUNCH_APP2,
                       &cursor_key_list);
  BuildKeyMatcherList(
      {ui::mojom::KeyboardCode::SHIFT, ui::mojom::KeyboardCode::CONTROL,
       ui::mojom::KeyboardCode::MENU,
       ui::mojom::KeyboardCode::LWIN,  // Search key == VKEY_LWIN.
       ui::mojom::KeyboardCode::WLAN, ui::mojom::KeyboardCode::POWER,
       ui::mojom::KeyboardCode::BRIGHTNESS_DOWN,
       ui::mojom::KeyboardCode::BRIGHTNESS_UP,
       ui::mojom::KeyboardCode::KBD_BRIGHTNESS_DOWN,
       ui::mojom::KeyboardCode::KBD_BRIGHTNESS_UP},
      &cursor_key_list);

  window_manager_client_->SetKeyEventsThatDontHideCursor(
      std::move(cursor_key_list));
}

void WindowManager::InstallFrameDecorationValues() {
  ui::mojom::FrameDecorationValuesPtr frame_decoration_values =
      ui::mojom::FrameDecorationValues::New();
  const gfx::Insets client_area_insets =
      NonClientFrameController::GetPreferredClientAreaInsets();
  frame_decoration_values->normal_client_area_insets = client_area_insets;
  frame_decoration_values->maximized_client_area_insets = client_area_insets;
  frame_decoration_values->max_title_bar_button_width =
      NonClientFrameController::GetMaxTitleBarButtonWidth();
  window_manager_client_->SetFrameDecorationValues(
      std::move(frame_decoration_values));
}

void WindowManager::Shutdown() {
  if (!window_tree_client_)
    return;

  aura::client::CaptureClient* capture_client = wm_state_->capture_controller();
  pointer_watcher_event_router_->DetachFromCaptureClient(capture_client);
  window_tree_client_->capture_synchronizer()->DetachFromCaptureClient(
      capture_client);

  Shell::DeleteInstance();

  pointer_watcher_event_router_.reset();

  window_tree_client_.reset();
  window_manager_client_ = nullptr;
}

void WindowManager::OnEmbed(
    std::unique_ptr<aura::WindowTreeHostMus> window_tree_host) {
  // WindowManager should never see this, instead OnWmNewDisplay() is called.
  NOTREACHED();
}

void WindowManager::OnEmbedRootDestroyed(
    aura::WindowTreeHostMus* window_tree_host) {
  // WindowManager should never see this.
  NOTREACHED();
}

void WindowManager::OnLostConnection(aura::WindowTreeClient* client) {
  DCHECK_EQ(client, window_tree_client_.get());
  Shutdown();
  // TODO(sky): this case should trigger shutting down WindowManagerService too.
}

void WindowManager::OnPointerEventObserved(const ui::PointerEvent& event,
                                           int64_t display_id,
                                           aura::Window* target) {
  pointer_watcher_event_router_->OnPointerEventObserved(event, display_id,
                                                        target);
}

aura::PropertyConverter* WindowManager::GetPropertyConverter() {
  return property_converter_.get();
}

void WindowManager::SetWindowManagerClient(aura::WindowManagerClient* client) {
  window_manager_client_ = client;
  ash::Shell::set_window_manager_client(client);
}

void WindowManager::OnWmConnected() {
  // InstallFrameDecorationValues() must be called before the shell is created,
  // otherwise Mus attempts to notify clients with no frame decorations, which
  // triggers validation errors.
  InstallFrameDecorationValues();
  CreateShell();
  if (show_primary_host_on_connect_)
    Shell::GetPrimaryRootWindow()->GetHost()->Show();

  // TODO(hirono): wire up the file helper. http://crbug.com/768395
  Shell::Get()->InitWaylandServer(nullptr);
}

void WindowManager::OnWmAcceleratedWidgetAvailableForDisplay(
    int64_t display_id,
    gfx::AcceleratedWidget widget) {
  WindowTreeHostManager* manager = Shell::Get()->window_tree_host_manager();
  AshWindowTreeHost* host =
      manager->GetAshWindowTreeHostForDisplayId(display_id);
  // The display may have been destroyed before getting this async callback.
  if (host && host->AsWindowTreeHost()) {
    static_cast<aura::WindowTreeHostMus*>(host->AsWindowTreeHost())
        ->OverrideAcceleratedWidget(widget);
  }
}

void WindowManager::OnWmSetBounds(aura::Window* window,
                                  const gfx::Rect& bounds) {
  // TODO(sky): this indirectly sets bounds, which is against what
  // OnWmSetBounds() recommends doing. Remove that restriction, or fix this.
  window->SetBounds(bounds);
}

bool WindowManager::OnWmSetProperty(
    aura::Window* window,
    const std::string& name,
    std::unique_ptr<std::vector<uint8_t>>* new_data) {
  if (property_converter_->IsTransportNameRegistered(name))
    return true;
  DVLOG(1) << "unknown property changed, ignoring " << name;
  return false;
}

void WindowManager::OnWmSetModalType(aura::Window* window, ui::ModalType type) {
  ui::ModalType old_type = window->GetProperty(aura::client::kModalKey);
  if (type == old_type)
    return;

  window->SetProperty(aura::client::kModalKey, type);
  // Assume the client has positioned the window in the right container and
  // don't attempt to change the parent. This is currently true for Chrome
  // code, but likely there should be checks. Adding checks is complicated by
  // the fact that assumptions in GetSystemModalContainer() are not always
  // valid for Chrome code. In particular Chrome code may create system modal
  // dialogs without a transient parent that Chrome wants shown on the lock
  // screen.
}

void WindowManager::OnWmSetCanFocus(aura::Window* window, bool can_focus) {
  NonClientFrameController* non_client_frame_controller =
      NonClientFrameController::Get(window);
  if (non_client_frame_controller)
    non_client_frame_controller->set_can_activate(can_focus);
}

aura::Window* WindowManager::OnWmCreateTopLevelWindow(
    ui::mojom::WindowType window_type,
    std::map<std::string, std::vector<uint8_t>>* properties) {
  if (window_type == ui::mojom::WindowType::UNKNOWN) {
    LOG(WARNING) << "Request to create top level of unknown type, failing";
    return nullptr;
  }

  return CreateAndParentTopLevelWindow(this, window_type,
                                       property_converter_.get(), properties);
}

void WindowManager::OnWmClientJankinessChanged(
    const std::set<aura::Window*>& client_windows,
    bool janky) {
  for (auto* window : client_windows)
    window->SetProperty(kWindowIsJanky, janky);
}

void WindowManager::OnWmBuildDragImage(const gfx::Point& screen_location,
                                       const gfx::ImageSkia& drag_image,
                                       const gfx::Vector2d& drag_image_offset,
                                       ui::mojom::PointerKind source) {
  if (drag_image.isNull())
    return;

  // TODO(erg): Get the right display for this drag image. Right now, none of
  // the drag drop code is multidisplay aware.
  aura::Window* root_window = Shell::GetPrimaryRootWindow();

  ui::DragDropTypes::DragEventSource ui_source =
      source == ui::mojom::PointerKind::MOUSE
          ? ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE
          : ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
  std::unique_ptr<DragImageView> drag_view =
      std::make_unique<DragImageView>(root_window, ui_source);
  drag_view->SetImage(drag_image);
  gfx::Size size = drag_view->GetPreferredSize();
  gfx::Rect drag_image_bounds(screen_location - drag_image_offset, size);
  drag_view->SetBoundsInScreen(drag_image_bounds);
  drag_view->SetWidgetVisible(true);

  drag_state_ = std::make_unique<DragState>();
  drag_state_->view = std::move(drag_view);
  drag_state_->image_offset = drag_image_offset;
}

void WindowManager::OnWmMoveDragImage(const gfx::Point& screen_location) {
  if (drag_state_) {
    drag_state_->view->SetScreenPosition(screen_location -
                                         drag_state_->image_offset);
  }
}

void WindowManager::OnWmDestroyDragImage() {
  drag_state_.reset();
}

void WindowManager::OnWmWillCreateDisplay(const display::Display& display) {
  // Ash connects such that |automatically_create_display_roots| is false, which
  // means this should never be hit.
  NOTREACHED();
}

void WindowManager::OnWmNewDisplay(
    std::unique_ptr<aura::WindowTreeHostMus> window_tree_host,
    const display::Display& display) {
  // Ash connects such that |automatically_create_display_roots| is false, which
  // means this should never be hit.
  NOTREACHED();
}

void WindowManager::OnWmDisplayRemoved(
    aura::WindowTreeHostMus* window_tree_host) {
  // Ash connects such that |automatically_create_display_roots| is false, which
  // means this should never be hit.
  NOTREACHED();
}

void WindowManager::OnWmDisplayModified(const display::Display& display) {
  // TODO(sky): this shouldn't be called as we're passing false for
  // |automatically_create_display_roots|, but it currently is. Update mus.
}

void WindowManager::OnWmPerformMoveLoop(
    aura::Window* window,
    ui::mojom::MoveLoopSource source,
    const gfx::Point& cursor_location,
    const base::Callback<void(bool)>& on_done) {
  MoveEventHandler* handler = MoveEventHandler::GetForWindow(window);
  if (!handler) {
    on_done.Run(false);
    return;
  }

  DCHECK(!handler->IsDragInProgress());
  ::wm::WindowMoveSource aura_source =
      source == ui::mojom::MoveLoopSource::MOUSE
          ? ::wm::WINDOW_MOVE_SOURCE_MOUSE
          : ::wm::WINDOW_MOVE_SOURCE_TOUCH;
  handler->AttemptToStartDrag(cursor_location, HTCAPTION, aura_source, on_done);
}

void WindowManager::OnWmCancelMoveLoop(aura::Window* window) {
  MoveEventHandler* handler = MoveEventHandler::GetForWindow(window);
  if (handler)
    handler->RevertDrag();
}

ui::mojom::EventResult WindowManager::OnAccelerator(
    uint32_t id,
    const ui::Event& event,
    base::flat_map<std::string, std::vector<uint8_t>>* properties) {
  auto iter = accelerator_handlers_.find(GetAcceleratorNamespaceId(id));
  if (iter == accelerator_handlers_.end())
    return ui::mojom::EventResult::HANDLED;

  return iter->second->OnAccelerator(id, event, properties);
}

void WindowManager::OnCursorTouchVisibleChanged(bool enabled) {
  ShellPortMash::Get()->OnCursorTouchVisibleChanged(enabled);
}

void WindowManager::OnWmSetClientArea(
    aura::Window* window,
    const gfx::Insets& insets,
    const std::vector<gfx::Rect>& additional_client_areas) {
  NonClientFrameController* non_client_frame_controller =
      NonClientFrameController::Get(window);
  if (!non_client_frame_controller)
    return;
  non_client_frame_controller->SetClientArea(insets);
}

bool WindowManager::IsWindowActive(aura::Window* window) {
  return Shell::Get()->activation_client()->GetActiveWindow() == window;
}

void WindowManager::OnWmDeactivateWindow(aura::Window* window) {
  Shell::Get()->activation_client()->DeactivateWindow(window);
}

void WindowManager::OnWmPerformAction(aura::Window* window,
                                      const std::string& action) {
  if (action == mojom::kAddWindowToTabletMode)
    ash::Shell::Get()->tablet_mode_controller()->AddWindow(window);
}

void WindowManager::OnEventBlockedByModalWindow(aura::Window* window) {
  AnimateWindow(window, ::wm::WINDOW_ANIMATION_TYPE_BOUNCE);
}

}  // namespace ash
