/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Display.h"

#include <android-base/parseint.h>
#include <android-base/unique_fd.h>
#include <pthread.h>
#include <sched.h>
#include <sync/sync.h>
#include <sys/types.h>

#include <algorithm>
#include <atomic>
#include <numeric>
#include <sstream>
#include <thread>

#include "Common.h"
#include "Device.h"

namespace aidl::android::hardware::graphics::composer3::impl {
namespace {

bool isValidColorMode(ColorMode mode) {
  switch (mode) {
    case ColorMode::NATIVE:
    case ColorMode::STANDARD_BT601_625:
    case ColorMode::STANDARD_BT601_625_UNADJUSTED:
    case ColorMode::STANDARD_BT601_525:
    case ColorMode::STANDARD_BT601_525_UNADJUSTED:
    case ColorMode::STANDARD_BT709:
    case ColorMode::DCI_P3:
    case ColorMode::SRGB:
    case ColorMode::ADOBE_RGB:
    case ColorMode::DISPLAY_P3:
    case ColorMode::BT2020:
    case ColorMode::BT2100_PQ:
    case ColorMode::BT2100_HLG:
    case ColorMode::DISPLAY_BT2020:
      return true;
    default:
      return false;
  }
}

bool isValidRenderIntent(RenderIntent intent) {
  switch (intent) {
    case RenderIntent::COLORIMETRIC:
    case RenderIntent::ENHANCE:
    case RenderIntent::TONE_MAP_COLORIMETRIC:
    case RenderIntent::TONE_MAP_ENHANCE:
      return true;
    default:
      return false;
  }
}

bool isValidPowerMode(PowerMode mode) {
  switch (mode) {
    case PowerMode::OFF:
    case PowerMode::DOZE:
    case PowerMode::DOZE_SUSPEND:
    case PowerMode::ON:
    case PowerMode::ON_SUSPEND:
      return true;
    default:
      return false;
  }
}

}  // namespace

Display::Display(FrameComposer* composer, int64_t id)
    : mComposer(composer), mId(id), mVsyncThread(id) {
  setLegacyEdid();
}

Display::~Display() {}

HWC3::Error Display::init(const std::vector<DisplayConfig>& configs,
                          int32_t activeConfigId,
                          const std::optional<std::vector<uint8_t>>& edid) {
  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  for (const DisplayConfig& config : configs) {
    mConfigs.emplace(config.getId(), config);
  }

  mActiveConfigId = activeConfigId;

  auto bootConfigIdOpt = getBootConfigId();
  if (bootConfigIdOpt) {
    mActiveConfigId = *bootConfigIdOpt;
  }

  if (edid.has_value()) {
    mEdid = *edid;
  }

  auto it = mConfigs.find(activeConfigId);
  if (it == mConfigs.end()) {
    ALOGE("%s: display:%" PRId64 "missing config:%" PRId32, __FUNCTION__, mId,
          activeConfigId);
    return HWC3::Error::NoResources;
  }

  const auto& activeConfig = it->second;
  const auto activeConfigString = activeConfig.toString();
  ALOGD("%s display:%" PRId64 " with config:%s", __FUNCTION__, mId,
        activeConfigString.c_str());

  mVsyncThread.start(activeConfig.getVsyncPeriod());

  return HWC3::Error::None;
}

HWC3::Error Display::updateParameters(
    uint32_t width, uint32_t height, uint32_t dpiX, uint32_t dpiY,
    uint32_t refreshRateHz, const std::optional<std::vector<uint8_t>>& edid) {
  DEBUG_LOG("%s: updating display:%" PRId64
            " width:%d height:%d dpiX:%d dpiY:%d refreshRateHz:%d",
            __FUNCTION__, mId, width, height, dpiX, dpiY, refreshRateHz);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  auto it = mConfigs.find(*mActiveConfigId);
  if (it == mConfigs.end()) {
    ALOGE("%s: failed to find config %" PRId32, __func__, *mActiveConfigId);
    return HWC3::Error::NoResources;
  }
  it->second.setAttribute(DisplayAttribute::VSYNC_PERIOD,
                          1000 * 1000 * 1000 / refreshRateHz);
  it->second.setAttribute(DisplayAttribute::WIDTH, width);
  it->second.setAttribute(DisplayAttribute::HEIGHT, height);
  it->second.setAttribute(DisplayAttribute::DPI_X, dpiX);
  it->second.setAttribute(DisplayAttribute::DPI_Y, dpiY);

  if (edid.has_value()) {
    mEdid = *edid;
  }

  return HWC3::Error::None;
}

HWC3::Error Display::createLayer(int64_t* outLayerId) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  auto layer = std::make_unique<Layer>();

  const int64_t layerId = layer->getId();
  DEBUG_LOG("%s: created layer:%" PRId64, __FUNCTION__, layerId);

  mLayers.emplace(layerId, std::move(layer));

  *outLayerId = layerId;

  return HWC3::Error::None;
}

HWC3::Error Display::destroyLayer(int64_t layerId) {
  DEBUG_LOG("%s: destroy layer:%" PRId64, __FUNCTION__, layerId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  auto it = mLayers.find(layerId);
  if (it == mLayers.end()) {
    ALOGE("%s display:%" PRId64 " has no such layer:%." PRId64, __FUNCTION__,
          mId, layerId);
    return HWC3::Error::BadLayer;
  }

  mOrderedLayers.erase(std::remove_if(mOrderedLayers.begin(),  //
                                      mOrderedLayers.end(),    //
                                      [layerId](Layer* layer) {
                                        return layer->getId() == layerId;
                                      }),
                       mOrderedLayers.end());

  mLayers.erase(it);

  DEBUG_LOG("%s: destroyed layer:%" PRId64, __FUNCTION__, layerId);
  return HWC3::Error::None;
}

HWC3::Error Display::getActiveConfig(int32_t* outConfig) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  if (!mActiveConfigId) {
    ALOGW("%s: display:%" PRId64 " has no active config.", __FUNCTION__, mId);
    return HWC3::Error::BadConfig;
  }

  *outConfig = *mActiveConfigId;
  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayAttribute(int32_t configId,
                                         DisplayAttribute attribute,
                                         int32_t* outValue) {
  auto attributeString = toString(attribute);
  DEBUG_LOG("%s: display:%" PRId64 " attribute:%s", __FUNCTION__, mId,
            attributeString.c_str());

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  auto it = mConfigs.find(configId);
  if (it == mConfigs.end()) {
    ALOGW("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
          configId);
    return HWC3::Error::BadConfig;
  }

  const DisplayConfig& config = it->second;
  *outValue = config.getAttribute(attribute);
  DEBUG_LOG("%s: display:%" PRId64 " attribute:%s value is %" PRIi32,
            __FUNCTION__, mId, attributeString.c_str(), *outValue);
  return HWC3::Error::None;
}

HWC3::Error Display::getColorModes(std::vector<ColorMode>* outModes) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  outModes->clear();
  outModes->insert(outModes->end(), mColorModes.begin(), mColorModes.end());

  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayCapabilities(
    std::vector<DisplayCapability>* outCapabilities) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  outCapabilities->clear();
  outCapabilities->push_back(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);

  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayConfigs(std::vector<int32_t>* outConfigIds) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  outConfigIds->clear();
  outConfigIds->reserve(mConfigs.size());
  for (const auto& [configId, _] : mConfigs) {
    outConfigIds->push_back(configId);
  }

  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayConnectionType(DisplayConnectionType* outType) {
  if (IsCuttlefishFoldable() || IsAutoDevice()) {
    // Android Auto OS needs to set all displays to INTERNAL since they're used
    // for the passenger displays.
    // Workaround to force all displays to INTERNAL for cf_x86_64_foldable.
    // TODO(b/193568008): Allow configuring internal/external per display.
    *outType = DisplayConnectionType::INTERNAL;
  } else {
    // Other devices default to the first display INTERNAL, others EXTERNAL.
    *outType = mId == 0 ? DisplayConnectionType::INTERNAL
                        : DisplayConnectionType::EXTERNAL;
  }
  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayIdentificationData(
    DisplayIdentification* outIdentification) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  if (outIdentification == nullptr) {
    return HWC3::Error::BadParameter;
  }

  outIdentification->port = mId;
  outIdentification->data = mEdid;

  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayName(std::string* outName) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  *outName = mName;
  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayVsyncPeriod(int32_t* outVsyncPeriod) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  if (!mActiveConfigId) {
    ALOGE("%s : display:%" PRId64 " no active config", __FUNCTION__, mId);
    return HWC3::Error::BadConfig;
  }

  const auto it = mConfigs.find(*mActiveConfigId);
  if (it == mConfigs.end()) {
    ALOGE("%s : display:%" PRId64 " failed to find active config:%" PRId32,
          __FUNCTION__, mId, *mActiveConfigId);
    return HWC3::Error::BadConfig;
  }
  const DisplayConfig& activeConfig = it->second;

  *outVsyncPeriod = activeConfig.getAttribute(DisplayAttribute::VSYNC_PERIOD);
  return HWC3::Error::None;
}

HWC3::Error Display::getDisplayedContentSample(
    int64_t /*maxFrames*/, int64_t /*timestamp*/,
    DisplayContentSample* /*samples*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::getDisplayedContentSamplingAttributes(
    DisplayContentSamplingAttributes* /*outAttributes*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::getDisplayPhysicalOrientation(
    common::Transform* outOrientation) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  *outOrientation = common::Transform::NONE;

  return HWC3::Error::None;
}

HWC3::Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  // No supported types.
  outCapabilities->types.clear();

  return HWC3::Error::None;
}

HWC3::Error Display::getPerFrameMetadataKeys(
    std::vector<PerFrameMetadataKey>* outKeys) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  outKeys->clear();

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::getReadbackBufferAttributes(
    ReadbackBufferAttributes* outAttributes) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  outAttributes->format = common::PixelFormat::RGBA_8888;
  outAttributes->dataspace = common::Dataspace::UNKNOWN;

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::getReadbackBufferFence(
    ndk::ScopedFileDescriptor* /*outAcquireFence*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::getRenderIntents(ColorMode mode,
                                      std::vector<RenderIntent>* outIntents) {
  const auto modeString = toString(mode);
  DEBUG_LOG("%s: display:%" PRId64 "for mode:%s", __FUNCTION__, mId,
            modeString.c_str());

  outIntents->clear();

  if (!isValidColorMode(mode)) {
    DEBUG_LOG("%s: display:%" PRId64 "invalid mode:%s", __FUNCTION__, mId,
              modeString.c_str());
    return HWC3::Error::BadParameter;
  }

  outIntents->push_back(RenderIntent::COLORIMETRIC);

  return HWC3::Error::None;
}

HWC3::Error Display::getSupportedContentTypes(
    std::vector<ContentType>* outTypes) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  outTypes->clear();

  return HWC3::Error::None;
}

HWC3::Error Display::getDecorationSupport(
    std::optional<common::DisplayDecorationSupport>* outSupport) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  outSupport->reset();

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::registerCallback(
    const std::shared_ptr<IComposerCallback>& callback) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  mVsyncThread.setCallbacks(callback);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::setActiveConfig(int32_t configId) {
  DEBUG_LOG("%s: display:%" PRId64 " setting active config to %" PRId32,
            __FUNCTION__, mId, configId);

  VsyncPeriodChangeConstraints constraints;
  constraints.desiredTimeNanos = 0;
  constraints.seamlessRequired = false;

  VsyncPeriodChangeTimeline timeline;

  return setActiveConfigWithConstraints(configId, constraints, &timeline);
}

HWC3::Error Display::setActiveConfigWithConstraints(
    int32_t configId, const VsyncPeriodChangeConstraints& constraints,
    VsyncPeriodChangeTimeline* outTimeline) {
  DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId,
            configId);

  if (outTimeline == nullptr) {
    return HWC3::Error::BadParameter;
  }

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  if (mActiveConfigId == configId) {
    return HWC3::Error::None;
  }

  DisplayConfig* newConfig = getConfig(configId);
  if (newConfig == nullptr) {
    ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
          configId);
    return HWC3::Error::BadConfig;
  }

  if (constraints.seamlessRequired) {
    if (mActiveConfigId) {
      DisplayConfig* oldConfig = getConfig(*mActiveConfigId);
      if (oldConfig == nullptr) {
        ALOGE("%s: display:%" PRId64 " missing config:%" PRId32, __FUNCTION__,
              mId, *mActiveConfigId);
        return HWC3::Error::NoResources;
      }

      const int32_t newConfigGroup = newConfig->getConfigGroup();
      const int32_t oldConfigGroup = oldConfig->getConfigGroup();
      if (newConfigGroup != oldConfigGroup) {
        DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32
                  " seamless not supported between different config groups "
                  "old:%d vs new:%d",
                  __FUNCTION__, mId, configId, oldConfigGroup, newConfigGroup);
        return HWC3::Error::SeamlessNotAllowed;
      }
    }
  }

  mActiveConfigId = configId;

  if (mComposer == nullptr) {
    ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
    return HWC3::Error::NoResources;
  }

  HWC3::Error error = mComposer->onActiveConfigChange(this);
  if (error != HWC3::Error::None) {
    ALOGE("%s: display:%" PRId64 " composer failed to handle config change",
          __FUNCTION__, mId);
    return error;
  }

  int32_t vsyncPeriod;
  error = getDisplayVsyncPeriod(&vsyncPeriod);
  if (error != HWC3::Error::None) {
    ALOGE("%s: display:%" PRId64 " composer failed to handle config change",
          __FUNCTION__, mId);
    return error;
  }

  return mVsyncThread.scheduleVsyncUpdate(vsyncPeriod, constraints,
                                          outTimeline);
}

std::optional<int32_t> Display::getBootConfigId() {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  std::string val;
  HWC3::Error error = Device::getInstance().getPersistentKeyValue(
      std::to_string(mId), "", &val);
  if (error != HWC3::Error::None) {
    ALOGE("%s: display:%" PRId64 " failed to get persistent boot config",
          __FUNCTION__, mId);
    return std::nullopt;
  }

  if (val.empty()) {
    return std::nullopt;
  }

  int32_t configId = 0;
  if (!::android::base::ParseInt(val, &configId)) {
    ALOGE("%s: display:%" PRId64
          " failed to parse persistent boot config from: %s",
          __FUNCTION__, mId, val.c_str());
    return std::nullopt;
  }

  if (!hasConfig(configId)) {
    ALOGE("%s: display:%" PRId64 " invalid persistent boot config:%" PRId32,
          __FUNCTION__, mId, configId);
    return std::nullopt;
  }

  return configId;
}

HWC3::Error Display::setBootConfig(int32_t configId) {
  DEBUG_LOG("%s: display:%" PRId64 " config:%" PRId32, __FUNCTION__, mId,
            configId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  DisplayConfig* newConfig = getConfig(configId);
  if (newConfig == nullptr) {
    ALOGE("%s: display:%" PRId64 " bad config:%" PRId32, __FUNCTION__, mId,
          configId);
    return HWC3::Error::BadConfig;
  }

  const std::string key = std::to_string(mId);
  const std::string val = std::to_string(configId);
  HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val);
  if (error != HWC3::Error::None) {
    ALOGE("%s: display:%" PRId64 " failed to save persistent boot config",
          __FUNCTION__, mId);
    return error;
  }

  return HWC3::Error::None;
}

HWC3::Error Display::clearBootConfig() {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  const std::string key = std::to_string(mId);
  const std::string val = "";
  HWC3::Error error = Device::getInstance().setPersistentKeyValue(key, val);
  if (error != HWC3::Error::None) {
    ALOGE("%s: display:%" PRId64 " failed to save persistent boot config",
          __FUNCTION__, mId);
    return error;
  }

  return HWC3::Error::None;
}

HWC3::Error Display::getPreferredBootConfig(int32_t* outConfigId) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  std::vector<int32_t> configIds;
  for (const auto [configId, _] : mConfigs) {
    configIds.push_back(configId);
  }
  *outConfigId = *std::min_element(configIds.begin(), configIds.end());

  return HWC3::Error::None;
}

HWC3::Error Display::setAutoLowLatencyMode(bool /*on*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::setColorMode(ColorMode mode, RenderIntent intent) {
  const std::string modeString = toString(mode);
  const std::string intentString = toString(intent);
  DEBUG_LOG("%s: display:%" PRId64 " setting color mode:%s intent:%s",
            __FUNCTION__, mId, modeString.c_str(), intentString.c_str());

  if (!isValidColorMode(mode)) {
    ALOGE("%s: display:%" PRId64 " invalid color mode:%s", __FUNCTION__, mId,
          modeString.c_str());
    return HWC3::Error::BadParameter;
  }

  if (!isValidRenderIntent(intent)) {
    ALOGE("%s: display:%" PRId64 " invalid intent:%s", __FUNCTION__, mId,
          intentString.c_str());
    return HWC3::Error::BadParameter;
  }

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  if (mColorModes.count(mode) == 0) {
    ALOGE("%s: display %" PRId64 " mode %s not supported", __FUNCTION__, mId,
          modeString.c_str());
    return HWC3::Error::Unsupported;
  }

  mActiveColorMode = mode;
  return HWC3::Error::None;
}

HWC3::Error Display::setContentType(ContentType contentType) {
  auto contentTypeString = toString(contentType);
  DEBUG_LOG("%s: display:%" PRId64 " content type:%s", __FUNCTION__, mId,
            contentTypeString.c_str());

  if (contentType != ContentType::NONE) {
    return HWC3::Error::Unsupported;
  }

  return HWC3::Error::None;
}

HWC3::Error Display::setDisplayedContentSamplingEnabled(
    bool /*enable*/, FormatColorComponent /*componentMask*/,
    int64_t /*maxFrames*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::setPowerMode(PowerMode mode) {
  auto modeString = toString(mode);
  DEBUG_LOG("%s: display:%" PRId64 " to mode:%s", __FUNCTION__, mId,
            modeString.c_str());

  if (!isValidPowerMode(mode)) {
    ALOGE("%s: display:%" PRId64 " invalid mode:%s", __FUNCTION__, mId,
          modeString.c_str());
    return HWC3::Error::BadParameter;
  }

  if (mode == PowerMode::DOZE || mode == PowerMode::DOZE_SUSPEND ||
      mode == PowerMode::ON_SUSPEND) {
    ALOGE("%s display %" PRId64 " mode:%s not supported", __FUNCTION__, mId,
          modeString.c_str());
    return HWC3::Error::Unsupported;
  }

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  if (IsCuttlefish()) {
    if (int fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC); fd != -1) {
      std::ostringstream stream;
      stream << "VIRTUAL_DEVICE_DISPLAY_POWER_MODE_CHANGED display=" << mId
             << " mode=" << modeString;
      std::string message = stream.str();
      write(fd, message.c_str(), message.length());
      close(fd);
    }
  }

  mPowerMode = mode;
  return HWC3::Error::None;
}

HWC3::Error Display::setReadbackBuffer(const buffer_handle_t buffer,
                                       const ndk::ScopedFileDescriptor& fence) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  mReadbackBuffer.set(buffer, fence);

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::setVsyncEnabled(bool enabled) {
  DEBUG_LOG("%s: display:%" PRId64 " setting vsync %s", __FUNCTION__, mId,
            (enabled ? "on" : "off"));

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  return mVsyncThread.setVsyncEnabled(enabled);
}

HWC3::Error Display::setIdleTimerEnabled(int32_t timeoutMs) {
  DEBUG_LOG("%s: display:%" PRId64 " timeout:%" PRId32, __FUNCTION__, mId,
            timeoutMs);

  (void)timeoutMs;

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::setColorTransform(
    const std::vector<float>& transformMatrix) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  if (transformMatrix.size() < 16) {
    ALOGE("%s: display:%" PRId64 " has non 4x4 matrix, size:%zu", __FUNCTION__,
          mId, transformMatrix.size());
    return HWC3::Error::BadParameter;
  }

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  auto& colorTransform = mColorTransform.emplace();
  std::copy_n(transformMatrix.data(), colorTransform.size(),
              colorTransform.begin());

  return HWC3::Error::None;
}

HWC3::Error Display::setBrightness(float brightness) {
  DEBUG_LOG("%s: display:%" PRId64 " brightness:%f", __FUNCTION__, mId,
            brightness);

  if (brightness < 0.0f) {
    ALOGE("%s: display:%" PRId64 " invalid brightness:%f", __FUNCTION__, mId,
          brightness);
    return HWC3::Error::BadParameter;
  }

  return HWC3::Error::Unsupported;
}

HWC3::Error Display::setClientTarget(
    buffer_handle_t buffer, const ndk::ScopedFileDescriptor& fence,
    common::Dataspace /*dataspace*/,
    const std::vector<common::Rect>& /*damage*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  mClientTarget.set(buffer, fence);

  mComposer->onDisplayClientTargetSet(this);
  return HWC3::Error::None;
}

HWC3::Error Display::setOutputBuffer(
    buffer_handle_t /*buffer*/, const ndk::ScopedFileDescriptor& /*fence*/) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  // TODO: for virtual display
  return HWC3::Error::None;
}

HWC3::Error Display::setExpectedPresentTime(
    const std::optional<ClockMonotonicTimestamp>& expectedPresentTime) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  if (!expectedPresentTime.has_value()) {
    return HWC3::Error::None;
  }

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  mExpectedPresentTime.emplace(
      asTimePoint(expectedPresentTime->timestampNanos));

  return HWC3::Error::None;
}

HWC3::Error Display::validate(DisplayChanges* outChanges) {
  ATRACE_CALL();

  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  mPendingChanges.reset();

  mOrderedLayers.clear();
  mOrderedLayers.reserve(mLayers.size());
  for (auto& [_, layerPtr] : mLayers) {
    mOrderedLayers.push_back(layerPtr.get());
  }
  std::sort(mOrderedLayers.begin(), mOrderedLayers.end(),
            [](const Layer* layerA, const Layer* layerB) {
              const auto zA = layerA->getZOrder();
              const auto zB = layerB->getZOrder();
              if (zA != zB) {
                return zA < zB;
              }
              return layerA->getId() < layerB->getId();
            });

  if (mComposer == nullptr) {
    ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
    return HWC3::Error::NoResources;
  }

  HWC3::Error error = mComposer->validateDisplay(this, &mPendingChanges);
  if (error != HWC3::Error::None) {
    ALOGE("%s: display:%" PRId64 " failed to validate", __FUNCTION__, mId);
    return error;
  }

  if (mPendingChanges.hasAnyChanges()) {
    mPresentFlowState = PresentFlowState::WAITING_FOR_ACCEPT;
    DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_ACCEPT", __FUNCTION__,
              mId);
  } else {
    mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT;
    DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__,
              mId);
  }

  *outChanges = mPendingChanges;
  return HWC3::Error::None;
}

HWC3::Error Display::acceptChanges() {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  switch (mPresentFlowState) {
    case PresentFlowState::WAITING_FOR_VALIDATE: {
      ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId);
      return HWC3::Error::NotValidated;
    }
    case PresentFlowState::WAITING_FOR_ACCEPT:
    case PresentFlowState::WAITING_FOR_PRESENT: {
      break;
    }
  }

  if (mPendingChanges.compositionChanges) {
    const ChangedCompositionTypes& compositionChanges =
        *mPendingChanges.compositionChanges;
    for (const ChangedCompositionLayer& compositionChange :
         compositionChanges.layers) {
      const auto layerId = compositionChange.layer;
      const auto layerComposition = compositionChange.composition;
      auto* layer = getLayer(layerId);
      if (layer == nullptr) {
        ALOGE("%s: display:%" PRId64 " layer:%" PRId64
              " dropped before acceptChanges()?",
              __FUNCTION__, mId, layerId);
        continue;
      }

      layer->setCompositionType(layerComposition);
    }
  }
  mPendingChanges.reset();

  mPresentFlowState = PresentFlowState::WAITING_FOR_PRESENT;
  DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_PRESENT", __FUNCTION__,
            mId);

  return HWC3::Error::None;
}

HWC3::Error Display::present(
    ::android::base::unique_fd* outDisplayFence,
    std::unordered_map<int64_t, ::android::base::unique_fd>* outLayerFences) {
  ATRACE_CALL();

  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  outDisplayFence->reset();
  outLayerFences->clear();

  std::unique_lock<std::recursive_mutex> lock(mStateMutex);

  switch (mPresentFlowState) {
    case PresentFlowState::WAITING_FOR_VALIDATE: {
      ALOGE("%s: display %" PRId64 " failed, not validated", __FUNCTION__, mId);
      return HWC3::Error::NotValidated;
    }
    case PresentFlowState::WAITING_FOR_ACCEPT: {
      ALOGE("%s: display %" PRId64 " failed, changes not accepted",
            __FUNCTION__, mId);
      return HWC3::Error::NotValidated;
    }
    case PresentFlowState::WAITING_FOR_PRESENT: {
      break;
    }
  }
  mPresentFlowState = PresentFlowState::WAITING_FOR_VALIDATE;
  DEBUG_LOG("%s: display:%" PRId64 " now WAITING_FOR_VALIDATE", __FUNCTION__,
            mId);

  if (mComposer == nullptr) {
    ALOGE("%s: display:%" PRId64 " missing composer", __FUNCTION__, mId);
    return HWC3::Error::NoResources;
  }

  return mComposer->presentDisplay(this, outDisplayFence, outLayerFences);
}

bool Display::hasConfig(int32_t configId) const {
  return mConfigs.find(configId) != mConfigs.end();
}

DisplayConfig* Display::getConfig(int32_t configId) {
  auto it = mConfigs.find(configId);
  if (it != mConfigs.end()) {
    return &it->second;
  }
  return nullptr;
}

HWC3::Error Display::setEdid(std::vector<uint8_t> edid) {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  mEdid = edid;
  return HWC3::Error::None;
}

void Display::setLegacyEdid() {
  // thess EDIDs are carefully generated according to the EDID spec version 1.3,
  // more info can be found from the following file:
  //   frameworks/native/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
  // approved pnp ids can be found here: https://uefi.org/pnp_id_list
  // pnp id: GGL, name: EMU_display_0, last byte is checksum
  // display id is local:8141603649153536
  static constexpr const std::array<uint8_t, 128> kEdid0 = {
      0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
      0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
      0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
      0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
      0x70, 0x6c, 0x61, 0x79, 0x5f, 0x30, 0x00, 0x4b};

  // pnp id: GGL, name: EMU_display_1
  // display id is local:8140900251843329
  static constexpr const std::array<uint8_t, 128> kEdid1 = {
      0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
      0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
      0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
      0x2d, 0x40, 0x58, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
      0x70, 0x6c, 0x61, 0x79, 0x5f, 0x31, 0x00, 0x3b};

  // pnp id: GGL, name: EMU_display_2
  // display id is local:8140940453066754
  static constexpr const std::array<uint8_t, 128> kEdid2 = {
      0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78,
      0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27, 0x12, 0x48, 0x4c, 0x00,
      0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
      0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38,
      0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0xfc, 0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73,
      0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49};

  mEdid.clear();
  switch (mId) {
    case 0: {
      mEdid.insert(mEdid.end(), kEdid0.begin(), kEdid0.end());
      break;
    }
    case 1: {
      mEdid.insert(mEdid.end(), kEdid1.begin(), kEdid1.end());
      break;
    }
    case 2: {
      mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end());
      break;
    }
    default: {
      mEdid.insert(mEdid.end(), kEdid2.begin(), kEdid2.end());
      const uint32_t size = mEdid.size();
      // Update the name to EMU_display_<mID>
      mEdid[size - 3] = '0' + (uint8_t)mId;
      // Update the checksum byte
      uint8_t checksum = -(uint8_t)std::accumulate(
          mEdid.data(), mEdid.data() + size - 1, static_cast<uint8_t>(0));
      mEdid[size - 1] = checksum;
      break;
    }
  }
}

Layer* Display::getLayer(int64_t layerId) {
  auto it = mLayers.find(layerId);
  if (it == mLayers.end()) {
    ALOGE("%s Unknown layer:%" PRId64, __FUNCTION__, layerId);
    return nullptr;
  }

  return it->second.get();
}

buffer_handle_t Display::waitAndGetClientTargetBuffer() {
  DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId);

  ::android::base::unique_fd fence = mClientTarget.getFence();
  if (fence.ok()) {
    int err = sync_wait(fence.get(), 3000);
    if (err < 0 && errno == ETIME) {
      ALOGE("%s waited on fence %" PRId32 " for 3000 ms", __FUNCTION__,
            fence.get());
    }
  }

  return mClientTarget.getBuffer();
}

}  // namespace aidl::android::hardware::graphics::composer3::impl
