// Copyright 2017 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/display/display_synchronizer.h"

#include "ash/display/mirror_window_controller.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/shell.h"
#include "services/ui/public/interfaces/window_manager_constants.mojom.h"
#include "ui/aura/mus/window_manager_delegate.h"
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/managed_display_info.h"

namespace ash {
namespace {

aura::WindowTreeHostMus* ToWindowTreeHostMus(AshWindowTreeHost* ash_host) {
  return static_cast<aura::WindowTreeHostMus*>(ash_host->AsWindowTreeHost());
}

// Get the metrics for the display with the given |id|.
ui::mojom::WmViewportMetricsPtr GetMetricsForDisplay(int64_t id) {
  ui::mojom::WmViewportMetricsPtr metrics = ui::mojom::WmViewportMetrics::New();
  const display::ManagedDisplayInfo& display_info =
      Shell::Get()->display_manager()->GetDisplayInfo(id);
  metrics->bounds_in_pixels = display_info.bounds_in_native();
  metrics->device_scale_factor = display_info.device_scale_factor();
  metrics->ui_scale_factor = display_info.configured_ui_scale();
  return metrics;
}

}  // namespace

DisplaySynchronizer::DisplaySynchronizer(
    aura::WindowManagerClient* window_manager_client)
    : window_manager_client_(window_manager_client) {
  Shell::Get()->window_tree_host_manager()->AddObserver(this);
  Shell::Get()->display_manager()->AddObserver(this);
  SendDisplayConfigurationToServer();
}

DisplaySynchronizer::~DisplaySynchronizer() {
  Shell::Get()->display_manager()->RemoveObserver(this);
  Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
}

void DisplaySynchronizer::SendDisplayConfigurationToServer() {
  if (processing_display_changes_)
    return;

  display::DisplayManager* display_manager = Shell::Get()->display_manager();
  const size_t display_count = display_manager->GetNumDisplays();
  if (display_count == 0)
    return;

  std::vector<display::Display> displays;
  std::vector<ui::mojom::WmViewportMetricsPtr> metrics;
  for (size_t i = 0; i < display_count; ++i) {
    displays.push_back(display_manager->GetDisplayAt(i));
    metrics.push_back(GetMetricsForDisplay(displays[i].id()));
  }
  std::vector<display::Display> mirrors;
  MirrorWindowController* mirror_window_controller =
      Shell::Get()->window_tree_host_manager()->mirror_window_controller();
  for (const auto& mirror :
       display_manager->software_mirroring_display_list()) {
    if (::switches::IsMusHostingViz()) {
      // If mus is hosting viz, the window server handle mirrors internally.
      mirrors.push_back(mirror);
      metrics.push_back(GetMetricsForDisplay(mirror.id()));
    } else if (mirror_window_controller->GetAshWindowTreeHostForDisplayId(
                   mirror.id())) {
      // Otherwise, if MirrorWindowController constructed a window tree host
      // the window server should construct a normal ws::Display for the mirror.
      displays.push_back(mirror);
      metrics.push_back(GetMetricsForDisplay(mirror.id()));
    }
  }

  window_manager_client_->SetDisplayConfiguration(
      displays, std::move(metrics),
      WindowTreeHostManager::GetPrimaryDisplayId(), mirrors);

  sent_initial_config_ = true;
}

void DisplaySynchronizer::OnDisplaysInitialized() {
  SendDisplayConfigurationToServer();
}

void DisplaySynchronizer::OnDisplayConfigurationChanged() {
  SendDisplayConfigurationToServer();
}

void DisplaySynchronizer::OnWindowTreeHostReusedForDisplay(
    AshWindowTreeHost* window_tree_host,
    const display::Display& display) {
  aura::WindowTreeHostMus* window_tree_host_mus =
      ToWindowTreeHostMus(window_tree_host);
  if (window_tree_host_mus->display_id() == display.id())
    return;
  const display::ManagedDisplayInfo& display_info =
      Shell::Get()->display_manager()->GetDisplayInfo(display.id());
  ui::mojom::WmViewportMetricsPtr viewport_metrics =
      ui::mojom::WmViewportMetrics::New();
  viewport_metrics->bounds_in_pixels = display_info.bounds_in_native();
  viewport_metrics->device_scale_factor = display.device_scale_factor();
  viewport_metrics->ui_scale_factor = display_info.configured_ui_scale();
  window_manager_client_->AddDisplayReusingWindowTreeHost(
      ToWindowTreeHostMus(window_tree_host), display,
      std::move(viewport_metrics));
}

void DisplaySynchronizer::OnWindowTreeHostsSwappedDisplays(
    AshWindowTreeHost* host1,
    AshWindowTreeHost* host2) {
  DCHECK(host1);
  DCHECK(host2);
  window_manager_client_->SwapDisplayRoots(ToWindowTreeHostMus(host1),
                                           ToWindowTreeHostMus(host2));
}

void DisplaySynchronizer::OnWillProcessDisplayChanges() {
  DCHECK(!processing_display_changes_);
  processing_display_changes_ = true;
}

void DisplaySynchronizer::OnDidProcessDisplayChanges() {
  DCHECK(processing_display_changes_);
  processing_display_changes_ = false;
  SendDisplayConfigurationToServer();
}

void DisplaySynchronizer::OnDisplayMetricsChanged(
    const display::Display& display,
    uint32_t changed_metrics) {
  // Changing only the work area doesn't trigger
  // OnDisplayConfigurationChanged().
  // Wait for the initial config before sending anything as initial display
  // creation may trigger numerous calls to OnDisplayConfigurationChanged().
  if (sent_initial_config_ && changed_metrics == DISPLAY_METRIC_WORK_AREA)
    SendDisplayConfigurationToServer();
}

}  // namespace ash
