// Copyright 2018 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 "services/ui/ws2/window_service.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
#include "services/ui/common/switches.h"
#include "services/ui/public/interfaces/window_manager.mojom.h"
#include "services/ui/ws2/event_injector.h"
#include "services/ui/ws2/gpu_interface_provider.h"
#include "services/ui/ws2/remoting_event_injector.h"
#include "services/ui/ws2/screen_provider.h"
#include "services/ui/ws2/server_window.h"
#include "services/ui/ws2/user_activity_monitor.h"
#include "services/ui/ws2/window_server_test_impl.h"
#include "services/ui/ws2/window_service_delegate.h"
#include "services/ui/ws2/window_service_observer.h"
#include "services/ui/ws2/window_tree.h"
#include "services/ui/ws2/window_tree_factory.h"
#include "ui/aura/env.h"
#include "ui/base/mojo/clipboard_host.h"
#include "ui/wm/core/shadow_types.h"

namespace ui {
namespace ws2 {

WindowService::WindowService(
    WindowServiceDelegate* delegate,
    std::unique_ptr<GpuInterfaceProvider> gpu_interface_provider,
    aura::client::FocusClient* focus_client,
    bool decrement_client_ids)
    : delegate_(delegate),
      gpu_interface_provider_(std::move(gpu_interface_provider)),
      screen_provider_(std::make_unique<ScreenProvider>()),
      focus_client_(focus_client),
      user_activity_monitor_(std::make_unique<UserActivityMonitor>()),
      next_client_id_(decrement_client_ids ? kInitialClientIdDecrement
                                           : kInitialClientId),
      decrement_client_ids_(decrement_client_ids),
      ime_registrar_(&ime_driver_) {
  DCHECK(focus_client);  // A |focus_client| must be provided.
  // MouseLocationManager is necessary for providing the shared memory with the
  // location of the mouse to clients.
  aura::Env::GetInstance()->CreateMouseLocationManager();

  input_device_server_.RegisterAsObserver();

  // This property should be registered by the PropertyConverter constructor,
  // but that would create a dependency cycle between ui/wm and ui/aura.
  property_converter_.RegisterPrimitiveProperty(
      ::wm::kShadowElevationKey,
      ui::mojom::WindowManager::kShadowElevation_Property,
      aura::PropertyConverter::CreateAcceptAnyValueCallback());
}

WindowService::~WindowService() {
  // WindowTreeFactory owns WindowTrees created by way of WindowTreeFactory.
  // Deleting it should ensure there are no WindowTrees left. Additionally,
  // WindowTree makes use of ScreenProvider, so we need to ensure all the
  // WindowTrees are destroyed before ScreenProvider.
  window_tree_factory_.reset();
  DCHECK(window_trees_.empty());
}

ServerWindow* WindowService::GetServerWindowForWindowCreateIfNecessary(
    aura::Window* window) {
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window);
  if (server_window)
    return server_window;

  const viz::FrameSinkId frame_sink_id =
      ClientWindowId(kWindowServerClientId, next_window_id_++);
  CHECK_NE(0u, next_window_id_);
  const bool is_top_level = false;
  return ServerWindow::Create(window, nullptr, frame_sink_id, is_top_level);
}

std::unique_ptr<WindowTree> WindowService::CreateWindowTree(
    mojom::WindowTreeClient* window_tree_client,
    const std::string& client_name) {
  const ClientSpecificId client_id =
      decrement_client_ids_ ? next_client_id_-- : next_client_id_++;
  CHECK_NE(kInvalidClientId, next_client_id_);
  CHECK_NE(kWindowServerClientId, next_client_id_);
  auto window_tree = std::make_unique<WindowTree>(
      this, client_id, window_tree_client, client_name);
  window_trees_.insert(window_tree.get());
  return window_tree;
}

void WindowService::SetFrameDecorationValues(
    const gfx::Insets& client_area_insets,
    int max_title_bar_button_width) {
  screen_provider_->SetFrameDecorationValues(client_area_insets,
                                             max_title_bar_button_width);
}

void WindowService::SetDisplayForNewWindows(int64_t display_id) {
  screen_provider_->SetDisplayForNewWindows(display_id);
}

// static
bool WindowService::HasRemoteClient(const aura::Window* window) {
  return ServerWindow::GetMayBeNull(window);
}

void WindowService::AddObserver(WindowServiceObserver* observer) {
  observers_.AddObserver(observer);
}

void WindowService::RemoveObserver(WindowServiceObserver* observer) {
  observers_.RemoveObserver(observer);
}

void WindowService::OnFirstSurfaceActivation(const std::string& client_name) {
  if (surface_activation_callback_)
    std::move(surface_activation_callback_).Run(client_name);
}

void WindowService::OnWillDestroyWindowTree(WindowTree* tree) {
  for (WindowServiceObserver& observer : observers_)
    observer.OnWillDestroyClient(tree->client_id());

  window_trees_.erase(tree);
}

bool WindowService::RequestClose(aura::Window* window) {
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window);
  if (!server_window || !server_window->IsTopLevel())
    return false;

  server_window->owning_window_tree()->RequestClose(server_window);
  return true;
}

void WindowService::OnDisplayMetricsChanged(const display::Display& display,
                                            uint32_t changed_metrics) {
  screen_provider_->DisplayMetricsChanged(display, changed_metrics);
}

std::string WindowService::GetIdForDebugging(aura::Window* window) {
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window);
  if (!server_window)
    return std::string();
  return server_window->GetIdForDebugging();
}

void WindowService::OnStart() {
  test_config_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kUseTestConfig);

  event_injector_ = std::make_unique<EventInjector>(this);

  window_tree_factory_ = std::make_unique<WindowTreeFactory>(this);

  registry_.AddInterface(base::BindRepeating(
      &WindowService::BindClipboardHostRequest, base::Unretained(this)));
  registry_.AddInterface(base::BindRepeating(
      &EventInjector::AddBinding, base::Unretained(event_injector_.get())));
  registry_.AddInterface(base::BindRepeating(
      &WindowService::BindImeRegistrarRequest, base::Unretained(this)));
  registry_.AddInterface(base::BindRepeating(
      &WindowService::BindImeDriverRequest, base::Unretained(this)));
  registry_.AddInterface(base::BindRepeating(
      &WindowService::BindInputDeviceServerRequest, base::Unretained(this)));
  registry_.AddInterface(
      base::BindRepeating(&WindowService::BindRemotingEventInjectorRequest,
                          base::Unretained(this)));
  registry_.AddInterface(base::BindRepeating(
      &WindowService::BindUserActivityMonitorRequest, base::Unretained(this)));

  registry_with_source_info_.AddInterface<mojom::WindowTreeFactory>(
      base::BindRepeating(&WindowService::BindWindowTreeFactoryRequest,
                          base::Unretained(this)));

  // |gpu_interface_provider_| may be null in tests.
  if (gpu_interface_provider_) {
    gpu_interface_provider_->RegisterGpuInterfaces(&registry_);

#if defined(USE_OZONE)
    gpu_interface_provider_->RegisterOzoneGpuInterfaces(&registry_);
#endif
  }

  if (test_config_) {
    registry_.AddInterface<mojom::WindowServerTest>(base::BindRepeating(
        &WindowService::BindWindowServerTestRequest, base::Unretained(this)));
  }
}

void WindowService::OnBindInterface(
    const service_manager::BindSourceInfo& remote_info,
    const std::string& interface_name,
    mojo::ScopedMessagePipeHandle handle) {
  if (!registry_with_source_info_.TryBindInterface(interface_name, &handle,
                                                   remote_info)) {
    registry_.BindInterface(interface_name, std::move(handle));
  }
}

void WindowService::SetSurfaceActivationCallback(
    base::OnceCallback<void(const std::string&)> callback) {
  // Surface activation callbacks are expensive, and allowed only in tests.
  DCHECK(test_config_);
  DCHECK(surface_activation_callback_.is_null() || callback.is_null());
  surface_activation_callback_ = std::move(callback);
}

void WindowService::BindClipboardHostRequest(
    mojom::ClipboardHostRequest request) {
  if (!clipboard_host_)
    clipboard_host_ = std::make_unique<ClipboardHost>();
  clipboard_host_->AddBinding(std::move(request));
}

void WindowService::BindImeRegistrarRequest(
    mojom::IMERegistrarRequest request) {
  ime_registrar_.AddBinding(std::move(request));
}

void WindowService::BindImeDriverRequest(mojom::IMEDriverRequest request) {
  ime_driver_.AddBinding(std::move(request));
}

void WindowService::BindInputDeviceServerRequest(
    mojom::InputDeviceServerRequest request) {
  input_device_server_.AddBinding(std::move(request));
}

void WindowService::BindRemotingEventInjectorRequest(
    mojom::RemotingEventInjectorRequest request) {
  if (!remoting_event_injector_ && delegate_->GetSystemInputInjector()) {
    remoting_event_injector_ = std::make_unique<RemotingEventInjector>(
        delegate_->GetSystemInputInjector());
  }
  if (remoting_event_injector_)
    remoting_event_injector_->AddBinding(std::move(request));
}

void WindowService::BindUserActivityMonitorRequest(
    mojom::UserActivityMonitorRequest request) {
  user_activity_monitor_->AddBinding(std::move(request));
}

void WindowService::BindWindowServerTestRequest(
    mojom::WindowServerTestRequest request) {
  if (!test_config_)
    return;
  mojo::MakeStrongBinding(std::make_unique<WindowServerTestImpl>(this),
                          std::move(request));
}

void WindowService::BindWindowTreeFactoryRequest(
    mojom::WindowTreeFactoryRequest request,
    const service_manager::BindSourceInfo& source_info) {
  window_tree_factory_->AddBinding(std::move(request),
                                   source_info.identity.name());
}

}  // namespace ws2
}  // namespace ui
