// Copyright 2014 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 "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"

#include <stddef.h>

#include "base/command_line.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
#include "ui/ozone/common/gpu/ozone_gpu_messages.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/host/drm_cursor.h"
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
#include "ui/ozone/platform/drm/host/drm_overlay_candidates_host.h"
#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
#include "ui/ozone/platform/drm/host/gpu_thread_observer.h"

namespace ui {

namespace {

// Helper class that provides DrmCursor with a mechanism to send messages
// to the GPU process.
class CursorIPC : public DrmCursorProxy {
 public:
  CursorIPC(scoped_refptr<base::SingleThreadTaskRunner> send_runner,
            const base::Callback<void(IPC::Message*)>& send_callback);
  ~CursorIPC() override;

  // DrmCursorProxy implementation.
  void CursorSet(gfx::AcceleratedWidget window,
                 const std::vector<SkBitmap>& bitmaps,
                 const gfx::Point& point,
                 int frame_delay_ms) override;
  void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override;
  void InitializeOnEvdevIfNecessary() override;

 private:
  bool IsConnected();
  void Send(IPC::Message* message);

  scoped_refptr<base::SingleThreadTaskRunner> send_runner_;
  base::Callback<void(IPC::Message*)> send_callback_;

  DISALLOW_COPY_AND_ASSIGN(CursorIPC);
};

CursorIPC::CursorIPC(scoped_refptr<base::SingleThreadTaskRunner> send_runner,
                     const base::Callback<void(IPC::Message*)>& send_callback)
    : send_runner_(send_runner), send_callback_(send_callback) {}

CursorIPC::~CursorIPC() {}

bool CursorIPC::IsConnected() {
  return !send_callback_.is_null();
}

void CursorIPC::CursorSet(gfx::AcceleratedWidget window,
                          const std::vector<SkBitmap>& bitmaps,
                          const gfx::Point& point,
                          int frame_delay_ms) {
  Send(new OzoneGpuMsg_CursorSet(window, bitmaps, point, frame_delay_ms));
}

void CursorIPC::Move(gfx::AcceleratedWidget window, const gfx::Point& point) {
  Send(new OzoneGpuMsg_CursorMove(window, point));
}

void CursorIPC::InitializeOnEvdevIfNecessary() {}

void CursorIPC::Send(IPC::Message* message) {
  if (IsConnected() && send_runner_->PostTask(
                           FROM_HERE, base::BindOnce(send_callback_, message)))
    return;

  // Drop disconnected updates. The cursor will get set once we connect, via
  // SetDrmCursorProxy().
  delete message;
}

}  // namespace

DrmGpuPlatformSupportHost::DrmGpuPlatformSupportHost(DrmCursor* cursor)
    : ui_runner_(base::ThreadTaskRunnerHandle::IsSet()
                     ? base::ThreadTaskRunnerHandle::Get()
                     : nullptr),
      cursor_(cursor),
      weak_ptr_factory_(this) {
  if (ui_runner_) {
    weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
  } else {
    DCHECK(!features::IsMultiProcessMash());
  }
}

DrmGpuPlatformSupportHost::~DrmGpuPlatformSupportHost() {}

void DrmGpuPlatformSupportHost::AddGpuThreadObserver(
    GpuThreadObserver* observer) {
  gpu_thread_observers_.AddObserver(observer);

  if (IsConnected())
    observer->OnGpuThreadReady();
}

void DrmGpuPlatformSupportHost::RemoveGpuThreadObserver(
    GpuThreadObserver* observer) {
  gpu_thread_observers_.RemoveObserver(observer);
}

bool DrmGpuPlatformSupportHost::IsConnected() {
  return host_id_ >= 0 && channel_established_;
}

void DrmGpuPlatformSupportHost::OnGpuServiceLaunched(
    scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
    scoped_refptr<base::SingleThreadTaskRunner> io_runner,
    GpuHostBindInterfaceCallback binder,
    GpuHostTerminateCallback terminate_callback) {
  NOTREACHED() << "DrmGpuPlatformSupportHost::OnGpuServiceLaunched shouldn't "
                  "be used with pre-mojo IPC";
}

void DrmGpuPlatformSupportHost::OnGpuProcessLaunched(
    int host_id,
    scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
    scoped_refptr<base::SingleThreadTaskRunner> send_runner,
    const base::Callback<void(IPC::Message*)>& send_callback) {
  // If there was a task runner set during construction, prefer using that.
  if (!ui_runner_) {
    ui_runner_ = std::move(ui_runner);
    weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
  }
  DCHECK(!ui_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("drm", "DrmGpuPlatformSupportHost::OnGpuProcessLaunched",
               "host_id", host_id);
  host_id_ = host_id;
  send_runner_ = std::move(send_runner);
  send_callback_ = send_callback;

  for (GpuThreadObserver& observer : gpu_thread_observers_)
    observer.OnGpuProcessLaunched();

  ui_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&DrmGpuPlatformSupportHost::OnChannelEstablished,
                     weak_ptr_));
}

void DrmGpuPlatformSupportHost::OnChannelDestroyed(int host_id) {
  TRACE_EVENT1("drm", "DrmGpuPlatformSupportHost::OnChannelDestroyed",
               "host_id", host_id);

  if (host_id_ == host_id) {
    cursor_->ResetDrmCursorProxy();
    host_id_ = -1;
    channel_established_ = false;
    send_runner_ = nullptr;
    send_callback_.Reset();
    for (GpuThreadObserver& observer : gpu_thread_observers_)
      observer.OnGpuThreadRetired();
  }

}

void DrmGpuPlatformSupportHost::OnMessageReceived(const IPC::Message& message) {
  DCHECK(ui_runner_);
  if (ui_runner_->BelongsToCurrentThread()) {
    if (OnMessageReceivedForDrmDisplayHostManager(message))
      return;
    OnMessageReceivedForDrmOverlayManager(message);
  } else {
    ui_runner_->PostTask(
        FROM_HERE, base::BindOnce(&DrmGpuPlatformSupportHost::OnMessageReceived,
                                  weak_ptr_, message));
  }
}

bool DrmGpuPlatformSupportHost::Send(IPC::Message* message) {
  if (IsConnected() && send_runner_->PostTask(
                           FROM_HERE, base::BindOnce(send_callback_, message)))
    return true;

  delete message;
  return false;
}

// DisplayHost
void DrmGpuPlatformSupportHost::RegisterHandlerForDrmDisplayHostManager(
    DrmDisplayHostManager* handler) {
  display_manager_ = handler;
}

void DrmGpuPlatformSupportHost::UnRegisterHandlerForDrmDisplayHostManager() {
  display_manager_ = nullptr;
}

void DrmGpuPlatformSupportHost::OnChannelEstablished() {
  TRACE_EVENT0("drm", "DrmGpuPlatformSupportHost::OnChannelEstablished");
  channel_established_ = true;

  for (GpuThreadObserver& observer : gpu_thread_observers_)
    observer.OnGpuThreadReady();

  // The cursor is special since it will process input events on the IO thread
  // and can by-pass the UI thread. This means that we need to special case it
  // and notify it after all other observers/handlers are notified such that the
  // (windowing) state on the GPU can be initialized before the cursor is
  // allowed to IPC messages (which are targeted to a specific window).
  cursor_->SetDrmCursorProxy(
      std::make_unique<CursorIPC>(send_runner_, send_callback_));
}

bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmDisplayHostManager(
    const IPC::Message& message) {
  bool handled = true;

  IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays,
                        OnUpdateNativeDisplays)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateReceived, OnHDCPStateReceived)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateUpdated, OnHDCPStateUpdated)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlTaken, OnTakeDisplayControl)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlRelinquished,
                        OnRelinquishDisplayControl)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void DrmGpuPlatformSupportHost::OnUpdateNativeDisplays(
    const std::vector<DisplaySnapshot_Params>& params) {
  display_manager_->GpuHasUpdatedNativeDisplays(params);
}

void DrmGpuPlatformSupportHost::OnDisplayConfigured(int64_t display_id,
                                                    bool status) {
  display_manager_->GpuConfiguredDisplay(display_id, status);
}

void DrmGpuPlatformSupportHost::OnHDCPStateReceived(int64_t display_id,
                                                    bool status,
                                                    display::HDCPState state) {
  display_manager_->GpuReceivedHDCPState(display_id, status, state);
}

void DrmGpuPlatformSupportHost::OnHDCPStateUpdated(int64_t display_id,
                                                   bool status) {
  display_manager_->GpuUpdatedHDCPState(display_id, status);
}

void DrmGpuPlatformSupportHost::OnTakeDisplayControl(bool status) {
  display_manager_->GpuTookDisplayControl(status);
}

void DrmGpuPlatformSupportHost::OnRelinquishDisplayControl(bool status) {
  display_manager_->GpuRelinquishedDisplayControl(status);
}

bool DrmGpuPlatformSupportHost::GpuRefreshNativeDisplays() {
  return Send(new OzoneGpuMsg_RefreshNativeDisplays());
}

bool DrmGpuPlatformSupportHost::GpuTakeDisplayControl() {
  return Send(new OzoneGpuMsg_TakeDisplayControl());
}

bool DrmGpuPlatformSupportHost::GpuRelinquishDisplayControl() {
  return Send(new OzoneGpuMsg_RelinquishDisplayControl());
}

bool DrmGpuPlatformSupportHost::GpuAddGraphicsDevice(const base::FilePath& path,
                                                     base::ScopedFD fd) {
  IPC::Message* message = new OzoneGpuMsg_AddGraphicsDevice(
      path, base::FileDescriptor(std::move(fd)));

  // This function may be called from two places:
  // - DrmDisplayHostManager::OnGpuProcessLaunched() invoked synchronously
  //   by GpuProcessHost::Init() on IO thread, which is the same thread as
  //   |send_runner_|. In this case we can synchronously send the IPC;
  // - DrmDisplayHostManager::OnAddGraphicsDevice() on UI thread. In this
  //   case we need to post the send task to IO thread.
  if (send_runner_ && send_runner_->BelongsToCurrentThread()) {
    DCHECK(!send_callback_.is_null());
    send_callback_.Run(message);
    return true;
  }

  return Send(message);
}

bool DrmGpuPlatformSupportHost::GpuRemoveGraphicsDevice(
    const base::FilePath& path) {
  return Send(new OzoneGpuMsg_RemoveGraphicsDevice(path));
}

// Overlays
void DrmGpuPlatformSupportHost::RegisterHandlerForDrmOverlayManager(
    DrmOverlayManager* handler) {
  overlay_manager_ = handler;
}

void DrmGpuPlatformSupportHost::UnRegisterHandlerForDrmOverlayManager() {
  overlay_manager_ = nullptr;
}

bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmOverlayManager(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
    IPC_MESSAGE_HANDLER(OzoneHostMsg_OverlayCapabilitiesReceived,
                        OnOverlayResult)
    // TODO(rjk): insert the extra
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void DrmGpuPlatformSupportHost::OnOverlayResult(
    gfx::AcceleratedWidget widget,
    const std::vector<OverlayCheck_Params>& params,
    const std::vector<OverlayCheckReturn_Params>& param_returns) {
  auto candidates = CreateOverlaySurfaceCandidateListFrom(params);
  auto returns = CreateOverlayStatusListFrom(param_returns);
  overlay_manager_->GpuSentOverlayResult(widget, candidates, returns);
}

bool DrmGpuPlatformSupportHost::GpuCheckOverlayCapabilities(
    gfx::AcceleratedWidget widget,
    const OverlaySurfaceCandidateList& candidates) {
  auto params = CreateParamsFromOverlaySurfaceCandidate(candidates);
  return Send(new OzoneGpuMsg_CheckOverlayCapabilities(widget, params));
}

// DrmDisplayHost
bool DrmGpuPlatformSupportHost::GpuConfigureNativeDisplay(
    int64_t display_id,
    const ui::DisplayMode_Params& display_mode,
    const gfx::Point& point) {
  return Send(
      new OzoneGpuMsg_ConfigureNativeDisplay(display_id, display_mode, point));
}

bool DrmGpuPlatformSupportHost::GpuDisableNativeDisplay(int64_t display_id) {
  return Send(new OzoneGpuMsg_DisableNativeDisplay(display_id));
}

bool DrmGpuPlatformSupportHost::GpuGetHDCPState(int64_t display_id) {
  return Send(new OzoneGpuMsg_GetHDCPState(display_id));
}

bool DrmGpuPlatformSupportHost::GpuSetHDCPState(int64_t display_id,
                                                display::HDCPState state) {
  return Send(new OzoneGpuMsg_SetHDCPState(display_id, state));
}

bool DrmGpuPlatformSupportHost::GpuSetColorMatrix(
    int64_t display_id,
    const std::vector<float>& color_matrix) {
  return Send(new OzoneGpuMsg_SetColorMatrix(display_id, color_matrix));
}

bool DrmGpuPlatformSupportHost::GpuSetGammaCorrection(
    int64_t display_id,
    const std::vector<display::GammaRampRGBEntry>& degamma_lut,
    const std::vector<display::GammaRampRGBEntry>& gamma_lut) {
  return Send(
      new OzoneGpuMsg_SetGammaCorrection(display_id, degamma_lut, gamma_lut));
}

bool DrmGpuPlatformSupportHost::GpuDestroyWindow(
    gfx::AcceleratedWidget widget) {
  return Send(new OzoneGpuMsg_DestroyWindow(widget));
}

bool DrmGpuPlatformSupportHost::GpuCreateWindow(gfx::AcceleratedWidget widget) {
  return Send(new OzoneGpuMsg_CreateWindow(widget));
}

bool DrmGpuPlatformSupportHost::GpuWindowBoundsChanged(
    gfx::AcceleratedWidget widget,
    const gfx::Rect& bounds) {
  return Send(new OzoneGpuMsg_WindowBoundsChanged(widget, bounds));
}

}  // namespace ui
