/*
* Copyright (c) 2021 The Linux Foundation. All rights reserved.
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above
*       copyright notice, this list of conditions and the following
*       disclaimer in the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of The Linux Foundation nor the names of its
*       contributors may be used to endorse or promote products derived
*       from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "DisplayConfigAIDL.h"

using sdm::Locker;
using ::aidl::android::hardware::common::NativeHandle;

namespace aidl {
namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace config {

DisplayConfigAIDL::DisplayConfigAIDL(){
  hwc_session_ = HWCSession::GetInstance();
}

DisplayConfigAIDL::DisplayConfigAIDL(HWCSession *hwc_session){
  if (!hwc_session) {
    ALOGE("%s: hwc_session:%p is invalid", __FUNCTION__, hwc_session);
  } else {
    hwc_session_ = hwc_session;
  }
}

int MapDisplayType(DisplayType dpy) {
  switch (dpy) {
    case DisplayType::PRIMARY:
      return qdutils::DISPLAY_PRIMARY;

    case DisplayType::EXTERNAL:
      return qdutils::DISPLAY_EXTERNAL;

    case DisplayType::VIRTUAL:
      return qdutils::DISPLAY_VIRTUAL;

    case DisplayType::BUILTIN2:
      return qdutils::DISPLAY_BUILTIN_2;

    default:
      break;
  }

  return -EINVAL;
}

sdm::HWCDisplay::DisplayStatus MapExternalStatus(ExternalStatus status) {
  switch (status) {
    case ExternalStatus::OFFLINE:
      return sdm::HWCDisplay::kDisplayStatusOffline;

    case ExternalStatus::ONLINE:
      return sdm::HWCDisplay::kDisplayStatusOnline;

    case ExternalStatus::PAUSE:
      return sdm::HWCDisplay::kDisplayStatusPause;

    case ExternalStatus::RESUME:
      return sdm::HWCDisplay::kDisplayStatusResume;

    default:
      break;
  }

  return sdm::HWCDisplay::kDisplayStatusInvalid;
}

int DisplayConfigAIDL::IsPowerModeOverrideSupported(uint32_t disp_id, bool *supported) {
  if (!hwc_session_->async_powermode_ || (disp_id > sdm::HWCCallbacks::kNumRealDisplays)) {
    ALOGW("%s: Power mode override is not supported on display:%d", __FUNCTION__, disp_id);
    *supported = false;
  } else {
    *supported = true;
  }

  return 0;
}

bool WaitForResourceNeeded(HWC2::PowerMode prev_mode, HWC2::PowerMode new_mode) {
  return ((prev_mode == HWC2::PowerMode::Off) &&
          (new_mode == HWC2::PowerMode::On || new_mode == HWC2::PowerMode::Doze));
}

ScopedAStatus DisplayConfigAIDL::isDisplayConnected(DisplayType dpy, bool* connected) {
  int disp_id = MapDisplayType(dpy);
  int disp_idx = hwc_session_->GetDisplayIndex(disp_id);

  if (disp_idx == -1) {
    ALOGE("%s: Invalid display = %d", __FUNCTION__, disp_id);
    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  } else {
    SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_idx]);
    *connected = hwc_session_->hwc_display_[disp_idx];
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setDisplayStatus(DisplayType dpy, ExternalStatus status) {
  int disp_id = MapDisplayType(dpy);
  sdm::HWCDisplay::DisplayStatus external_status = MapExternalStatus(status);

  if (hwc_session_->SetDisplayStatus(disp_id, external_status) != 0) {
    ALOGW("%s: Setting status:%d to display:%d failed", __FUNCTION__, status, disp_id);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::configureDynRefreshRate(DynRefreshRateOp op, int refreshRate) {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]);
  sdm::HWCDisplay *hwc_display = hwc_session_->hwc_display_[HWC_DISPLAY_PRIMARY];

  if (!hwc_display) {
    ALOGW("%s: Display = %d is not connected.", __FUNCTION__, HWC_DISPLAY_PRIMARY);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  switch (op) {
    case DynRefreshRateOp::DISABLE_METADATA:
      hwc_display->Perform(sdm::HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, false);
      break;

    case DynRefreshRateOp::ENABLE_METADATA:
      hwc_display->Perform(sdm::HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, true);
      break;

    case DynRefreshRateOp::SET_BINDER:
      hwc_display->Perform(sdm::HWCDisplayBuiltIn::SET_BINDER_DYN_REFRESH_RATE, refreshRate);
      break;

    default:
      ALOGW("%s: Invalid operation %d", __FUNCTION__, op);
      return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getConfigCount(DisplayType dpy, int* count) {
  int error = hwc_session_->GetConfigCount(MapDisplayType(dpy), (uint32_t*) count);
  if (error == -EINVAL) {
    ALOGW("%s: Failed to retrieve config count for display:%d", __FUNCTION__, dpy);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getActiveConfig(DisplayType dpy, int* config) {
  int disp_id = MapDisplayType(dpy);

  int error = hwc_session_->GetActiveConfigIndex(disp_id, (uint32_t*) config);
  if (error == -EINVAL) {
    ALOGW("%s: Failed to retrieve the active config index for display:%d", __FUNCTION__, dpy);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  return ScopedAStatus::ok();

}

ScopedAStatus DisplayConfigAIDL::setActiveConfig(DisplayType dpy, int config) {
  int disp_id = MapDisplayType(dpy);

  if (hwc_session_->SetActiveConfigIndex(disp_id, (uint32_t) config) == -EINVAL) {
    ALOGW("%s: Failed to set active config index to display:%d", __FUNCTION__, dpy);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getDisplayAttributes(int configIndex, DisplayType dpy,
                                                      Attributes* attributes) {
  int error = -EINVAL;
  int disp_id = MapDisplayType(dpy);
  int disp_idx = hwc_session_->GetDisplayIndex(disp_id);

  if (disp_idx == -1) {
    ALOGW("%s: Invalid display = %d", __FUNCTION__, disp_id);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  } else {
    SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_idx]);
    if (hwc_session_->hwc_display_[disp_idx]) {
      sdm::DisplayConfigVariableInfo var_info;
      error = hwc_session_->hwc_display_[disp_idx]->GetDisplayAttributesForConfig(INT(configIndex),
                                                                                  &var_info);
      if (!error) {
        attributes->vsyncPeriod = var_info.vsync_period_ns;
        attributes->xRes = var_info.x_pixels;
        attributes->yRes = var_info.y_pixels;
        attributes->xDpi = var_info.x_dpi;
        attributes->yDpi = var_info.y_dpi;
        attributes->panelType = DisplayPortType::DEFAULT;
        attributes->isYuv = var_info.is_yuv;
      }
    }
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setPanelBrightness(int level) {
  if (!(0 <= level && level <= 255)) {
    ALOGW("%s: Invalid panel brightness level :%d", __FUNCTION__, level);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  if (level == 0) {
    hwc_session_->SetDisplayBrightness(HWC_DISPLAY_PRIMARY, -1.0f);
  } else {
    hwc_session_->SetDisplayBrightness(HWC_DISPLAY_PRIMARY, (level - 1)/254.0f);
  }
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getPanelBrightness(int* level) {
  float brightness = -1.0f;

  hwc_session_->getDisplayBrightness(HWC_DISPLAY_PRIMARY, &brightness);
  if (brightness == -1.0f) {
    *level = 0;
  } else {
    *level = static_cast<uint32_t>(254.0f*brightness + 1);
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::minHdcpEncryptionLevelChanged(DisplayType dpy, int minEncLevel) {
  hwc_session_->MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), minEncLevel);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::refreshScreen() {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]);
  hwc_session_->callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::controlPartialUpdate(DisplayType dpy, bool enable) {
  hwc_session_->ControlPartialUpdate(MapDisplayType(dpy), enable);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::toggleScreenUpdate(bool on) {
  hwc_session_->ToggleScreenUpdate(on);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setIdleTimeout(int value) {
  hwc_session_->SetIdleTimeout(value);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getHDRCapabilities(DisplayType dpy, HDRCapsParams* caps) {
  int error = -EINVAL;

  do {
    int disp_id = MapDisplayType(dpy);
    int disp_idx = hwc_session_->GetDisplayIndex(disp_id);
    if (disp_idx == -1) {
      ALOGE("Invalid display = %d", disp_id);
      break;
    }

    SCOPE_LOCK(hwc_session_->locker_[disp_id]);
    sdm::HWCDisplay *hwc_display = hwc_session_->hwc_display_[disp_idx];
    if (!hwc_display) {
      ALOGW("Display = %d is not connected.", disp_idx);
      error = -ENODEV;
      break;
    }

    // query number of hdr types
    uint32_t out_num_types = 0;
    float out_max_luminance = 0.0f;
    float out_max_average_luminance = 0.0f;
    float out_min_luminance = 0.0f;
    if (hwc_display->GetHdrCapabilities(&out_num_types, nullptr, &out_max_luminance,
                                        &out_max_average_luminance, &out_min_luminance)
                                        != HWC2::Error::None) {
      break;
    }
    if (!out_num_types) {
      error = 0;
      break;
    }

    // query hdr caps
    caps->supportedHdrTypes.resize(out_num_types);

    if (hwc_display->GetHdrCapabilities(&out_num_types, caps->supportedHdrTypes.data(),
                                        &out_max_luminance, &out_max_average_luminance,
                                        &out_min_luminance) == HWC2::Error::None) {
      error = 0;
    }
  } while (false);

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setCameraLaunchStatus(int on) {
  hwc_session_->SetCameraLaunchStatus(on);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::displayBWTransactionPending(bool* status) {
  hwc_session_->DisplayBWTransactionPending(status);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setDisplayAnimating(long displayId, bool animating) {
  hwc_session_->CallDisplayFunction(displayId, &sdm::HWCDisplay::SetDisplayAnimating, animating);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::controlIdlePowerCollapse(bool enable, bool synchronous) {
  hwc_session_->ControlIdlePowerCollapse(enable, synchronous);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getWriteBackCapabilities(bool* isWbUbwcSupported) {
  hwc_session_->IsWbUbwcSupported(isWbUbwcSupported);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setDisplayDppsAdROI(int displayId, int hStart, int hEnd,
                                               int vStart, int vEnd, int factorIn, int factorOut) {

  hwc_session_->SetDisplayDppsAdROI(displayId, hStart, hEnd, vStart, vEnd, factorIn, factorOut);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::updateVSyncSourceOnPowerModeOff() {
  hwc_session_->update_vsync_on_power_off_ = true;
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::updateVSyncSourceOnPowerModeDoze() {
  hwc_session_->update_vsync_on_doze_ = true;
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setPowerMode(int dispId, PowerMode powerMode) {
  SCOPE_LOCK(hwc_session_->display_config_locker_);

  bool supported = false;
  IsPowerModeOverrideSupported(dispId, &supported);
  if (!supported) {
    ALOGW("%s: Set power mode:%d on display:%d is not supported", __FUNCTION__, powerMode, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
  }

  // Active builtin display needs revalidation
  hwc2_display_t active_builtin_disp_id = hwc_session_->GetActiveBuiltinDisplay();
  HWC2::PowerMode previous_mode = hwc_session_->hwc_display_[dispId]->GetCurrentPowerMode();

  ALOGI("%s: disp_id: %d power_mode: %d", __FUNCTION__, dispId, powerMode);
  sdm::HWCDisplay::HWCLayerStack stack = {};
  hwc2_display_t dummy_disp_id = hwc_session_->map_hwc_display_.at(dispId);

  // Power state transition start.
  // Acquire the display's power-state transition var read lock.
  hwc_session_->power_state_[dispId].Lock();
  hwc_session_->power_state_transition_[dispId] = true;
  hwc_session_->locker_[dispId].Lock();        // Lock the real display.
  hwc_session_->locker_[dummy_disp_id].Lock();  // Lock the corresponding dummy display.

  // Place the real display's layer-stack on the dummy display.
  hwc_session_->hwc_display_[dispId]->GetLayerStack(&stack);
  hwc_session_->hwc_display_[dummy_disp_id]->SetLayerStack(&stack);
  hwc_session_->hwc_display_[dummy_disp_id]->UpdatePowerMode(
                                       hwc_session_->hwc_display_[dispId]->GetCurrentPowerMode());

  hwc_session_->locker_[dummy_disp_id].Unlock();  // Release the dummy display.
  // Release the display's power-state transition var read lock.
  hwc_session_->power_state_[dispId].Unlock();

  // From now, till power-state transition ends, for operations that need to be non-blocking, do
  // those operations on the dummy display.

  // Perform the actual [synchronous] power-state change.
  hwc_session_->hwc_display_[dispId]->SetPowerMode(static_cast<HWC2::PowerMode>(powerMode),
                                                    false /* teardown */);

  // Power state transition end.
  // Acquire the display's power-state transition var read lock.
  hwc_session_->power_state_[dispId].Lock();
  hwc_session_->power_state_transition_[dispId] = false;
  hwc_session_->locker_[dummy_disp_id].Lock();  // Lock the dummy display.

  // Retrieve the real display's layer-stack from the dummy display.
  hwc_session_->hwc_display_[dummy_disp_id]->GetLayerStack(&stack);
  hwc_session_->hwc_display_[dispId]->SetLayerStack(&stack);
  // Read display has got layerstack. Update the fences.
  hwc_session_->hwc_display_[dispId]->PostPowerMode();

  hwc_session_->locker_[dummy_disp_id].Unlock();  // Release the dummy display.
 hwc_session_->locker_[dispId].Unlock();        // Release the real display.
  // Release the display's power-state transition var read lock.
  hwc_session_->power_state_[dispId].Unlock();

  HWC2::PowerMode new_mode = hwc_session_->hwc_display_[dispId]->GetCurrentPowerMode();
  if (active_builtin_disp_id < sdm::HWCCallbacks::kNumRealDisplays &&
      hwc_session_->hwc_display_[dispId]->IsFirstCommitDone() &&
      WaitForResourceNeeded(previous_mode, new_mode)) {
    hwc_session_->WaitForResources(true, active_builtin_disp_id, dispId);
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isPowerModeOverrideSupported(int dispId, bool* supported) {
  if (!hwc_session_->async_powermode_ || (dispId > sdm::HWCCallbacks::kNumRealDisplays)) {
    *supported = false;
  } else {
    *supported = true;
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isHDRSupported(int dispId, bool* supported) {
  if (dispId < 0 || dispId >= sdm::HWCCallbacks::kNumDisplays) {
    ALOGW("%s: Not valid display", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }
  SCOPE_LOCK(hwc_session_->hdr_locker_[dispId]);

  if (hwc_session_->is_hdr_display_.size() <= dispId) {
    ALOGW("%s: is_hdr_display_ is not initialized for display %d!! Reporting it as HDR not " \
          "supported", __FUNCTION__, dispId);

    *supported = false;
    return ScopedAStatus::ok();
  }

  *supported = static_cast<bool>(hwc_session_->is_hdr_display_[dispId]);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isWCGSupported(int dispId, bool* supported) {
  isHDRSupported(dispId, supported);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setLayerAsMask(int dispId, long layerId) {
  SCOPE_LOCK(hwc_session_->locker_[dispId]);
  sdm::HWCDisplay *hwc_display = hwc_session_->hwc_display_[dispId];
  if (!hwc_display) {
    ALOGW("%s: Display = %d is not connected.", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  if (hwc_session_->disable_mask_layer_hint_) {
    ALOGW("%s: Mask layer hint is disabled!", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
  }

  auto hwc_layer = hwc_display->GetHWCLayer(layerId);
  if (hwc_layer == nullptr) {
    ALOGW("%s: Failed to retrieve the hwc layer fpr display:%d", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  hwc_layer->SetLayerAsMask();
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getDebugProperty(const std::string& propName,
                                                  std::string* value) {
  std::string vendor_prop_name = DISP_PROP_PREFIX;
  int error = -EINVAL;
  char val[64] = {};

  vendor_prop_name += propName.c_str();
  if (sdm::HWCDebugHandler::Get()->GetProperty(vendor_prop_name.c_str(), val) == sdm::kErrorNone) {
    *value = val;
    error = 0;
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getActiveBuiltinDisplayAttributes(Attributes* attr) {
  int error = -EINVAL;
  hwc2_display_t disp_id = hwc_session_->GetActiveBuiltinDisplay();

  if (disp_id >= sdm::HWCCallbacks::kNumDisplays) {
    ALOGE("%s: Invalid display = %lu", __FUNCTION__, disp_id);
  } else {
    if (hwc_session_->hwc_display_[disp_id]) {
      uint32_t config_index = 0;
      HWC2::Error ret = hwc_session_->hwc_display_[disp_id]->GetActiveConfig(&config_index);
      if (ret != HWC2::Error::None) {
        return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
      }
      sdm::DisplayConfigVariableInfo var_info;
      error = hwc_session_->hwc_display_[disp_id]->GetDisplayAttributesForConfig(INT(config_index),
                                                                                 &var_info);
      if (!error) {
        attr->vsyncPeriod = var_info.vsync_period_ns;
        attr->xRes = var_info.x_pixels;
        attr->yRes = var_info.y_pixels;
        attr->xDpi = var_info.x_dpi;
        attr->yDpi = var_info.y_dpi;
        attr->panelType = DisplayPortType::DEFAULT;
        attr->isYuv = var_info.is_yuv;
      }
    }
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setPanelLuminanceAttributes(int dispId, float minLum,
                                                             float maxLum) {
  // currently doing only for virtual display
  if (dispId != static_cast<int>(DisplayType::VIRTUAL)) {
    ALOGW("%s: Setting panel luminance on non virtual display is not supported", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  // check for out of range luminance values
  if (minLum <= 0.0f || minLum >= 1.0f ||
      maxLum <= 100.0f || maxLum >= 1000.0f) {
    ALOGW("%s: Luminance values are out of range : minimum_luminance:%f maximum_luminance:%f",
          __FUNCTION__, minLum, maxLum);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  std::lock_guard<std::mutex> obj(hwc_session_->mutex_lum_);
  hwc_session_->set_min_lum_ = minLum;
  hwc_session_->set_max_lum_ = maxLum;
  ALOGI("%s: set max_lum %f, min_lum %f", __FUNCTION__, maxLum, minLum);

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isBuiltInDisplay(int dispId, bool* isBuiltIn) {
  if ((hwc_session_->map_info_primary_.client_id == dispId) &&
      (hwc_session_->map_info_primary_.disp_type == sdm::kBuiltIn)) {
    *isBuiltIn = true;
    return ScopedAStatus::ok();
  }

  for (auto &info : hwc_session_->map_info_builtin_) {
    if (dispId == info.client_id) {
      *isBuiltIn = true;
      return ScopedAStatus::ok();
    }
  }

  *isBuiltIn = false;
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isAsyncVDSCreationSupported(bool* supported) {
  if (!hwc_session_->async_vds_creation_) {
    *supported = false;
    return ScopedAStatus::ok();
  }

  *supported = true;
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::createVirtualDisplay(int width, int height, int format) {
  if (!hwc_session_->async_vds_creation_) {
    ALOGW("%s: Asynchronous virtual display creation is not supported.", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  if (!width || !height) {
    ALOGW("%s: Width and height provided are invalid.", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  hwc2_display_t virtual_id;
  hwc2_display_t active_builtin_disp_id = hwc_session_->GetActiveBuiltinDisplay();
  auto status = hwc_session_->CreateVirtualDisplayObj(width, height, &format,
                                                    &virtual_id);
  if (status == HWC2::Error::None) {
    ALOGI("%s, Created virtual display id:%" PRIu64 ", res: %dx%d",
          __FUNCTION__, virtual_id, width, height);

    if (active_builtin_disp_id < sdm::HWCCallbacks::kNumRealDisplays) {
      hwc_session_->WaitForResources(true, active_builtin_disp_id, virtual_id);
    }
  } else {
    ALOGE("%s: Failed to create virtual display: %s", __FUNCTION__, to_string(status).c_str());
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getSupportedDSIBitClks(int dispId, std::vector<long>* bitClks) {
  SCOPE_LOCK(hwc_session_->locker_[dispId]);
  if (!hwc_session_->hwc_display_[dispId]) {
    ALOGW("%s: Display:%d is not connected", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  hwc_session_->hwc_display_[dispId]->GetSupportedDSIClock((std::vector<uint64_t>*) bitClks);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getDSIClk(int dispId, long* bitClk) {
  SCOPE_LOCK(hwc_session_->locker_[dispId]);
  if (!hwc_session_->hwc_display_[dispId]) {
    ALOGW("%s: Invalid display:%d", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  hwc_session_->hwc_display_[dispId]->GetDynamicDSIClock((uint64_t*)bitClk);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setDSIClk(int dispId, long bitClk) {
   SCOPE_LOCK(hwc_session_->locker_[dispId]);
   if (!hwc_session_->hwc_display_[dispId]) {
     ALOGW("%s: Invalid display:%d", __FUNCTION__, dispId);
     return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
   }

   hwc_session_->hwc_display_[dispId]->SetDynamicDSIClock(bitClk);
   return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setQsyncMode(int dispId, QsyncMode mode) {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[dispId]);
  if (!hwc_session_->hwc_display_[dispId]) {
    ALOGW("%s: Invalid display:%d", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  sdm::QSyncMode qsync_mode = sdm::kQSyncModeNone;
  switch (mode) {
    case QsyncMode::NONE:
      qsync_mode = sdm::kQSyncModeNone;
      break;

    case QsyncMode::WAIT_FOR_FENCES_ONE_FRAME:
      qsync_mode = sdm::kQsyncModeOneShot;
      break;

    case QsyncMode::WAIT_FOR_FENCES_EACH_FRAME:
      qsync_mode = sdm::kQsyncModeOneShotContinuous;
      break;

    case QsyncMode::WAIT_FOR_COMMIT_EACH_FRAME:
      qsync_mode = sdm::kQSyncModeContinuous;
      break;
  }

  hwc_session_->hwc_display_[dispId]->SetQSyncMode(qsync_mode);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isSmartPanelConfig(int dispId, int configId, bool* isSmart) {
  SCOPE_LOCK(hwc_session_->locker_[dispId]);
  if (!hwc_session_->hwc_display_[dispId]) {
    ALOGE("%s: Display %d is not created yet.", __FUNCTION__, dispId);
    *isSmart = false;
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  if (hwc_session_->hwc_display_[dispId]->GetDisplayClass() != sdm::DISPLAY_CLASS_BUILTIN) {
    ALOGW("%s: Smart panel config is only supported on built in displays.", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  *isSmart = hwc_session_->hwc_display_[dispId]->IsSmartPanelConfig(configId);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isRotatorSupportedFormat(int halFormat, bool ubwc,
                                                          bool* supported) {
  if (!hwc_session_->core_intf_) {
    ALOGW("%s: core_intf_ not initialized.", __FUNCTION__);
    *supported = false;
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  int flag = ubwc ? qtigralloc::PRIV_FLAGS_UBWC_ALIGNED : 0;

  sdm::LayerBufferFormat sdm_format = sdm::HWCLayer::GetSDMFormat(halFormat, flag);

  *supported = hwc_session_->core_intf_->IsRotatorSupportedFormat(sdm_format);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::controlQsyncCallback(bool enable) {
  if (enable) {
    hwc_session_->qsync_callback_ = callback_;
  } else {
    hwc_session_->qsync_callback_.reset();
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::sendTUIEvent(DisplayType dpy, TUIEventType eventType) {
  int disp_id = MapDisplayType(dpy);

  switch(eventType) {
    case TUIEventType::PREPARE_TUI_TRANSITION:
      hwc_session_->TUITransitionPrepare(disp_id);
      break;

    case TUIEventType::START_TUI_TRANSITION:
      hwc_session_->TUITransitionStart(disp_id);
      break;

    case TUIEventType::END_TUI_TRANSITION:
      hwc_session_->TUITransitionEnd(disp_id);
      break;

    default:
      ALOGE("%s: Invalid event %d", __FUNCTION__, eventType);
      return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getDisplayHwId(int dispId, int* displayHwId) {
  int disp_idx = hwc_session_->GetDisplayIndex(dispId);
  if (disp_idx == -1) {
    ALOGE("%s: Invalid display = %d", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  SCOPE_LOCK(hwc_session_->locker_[dispId]);
  if (!hwc_session_->hwc_display_[disp_idx]) {
    ALOGW("%s: Display %d is not connected.", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  // Supported for Built-In displays only.
  if ((hwc_session_->map_info_primary_.client_id == dispId) &&
      (hwc_session_->map_info_primary_.disp_type == sdm::kBuiltIn)) {
    if (hwc_session_->map_info_primary_.sdm_id >= 0) {
      *displayHwId = static_cast<uint32_t>(hwc_session_->map_info_primary_.sdm_id);
      return ScopedAStatus::ok();
    }
  }

  for (auto &info : hwc_session_->map_info_builtin_) {
    if (dispId == info.client_id) {
      if (info.sdm_id >= 0) {
        *displayHwId = static_cast<uint32_t>(info.sdm_id);
        return ScopedAStatus::ok();
      }
    }
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::getSupportedDisplayRefreshRates(DisplayType dpy,
                                                         std::vector<int>* supportedRefreshRates) {

  hwc_session_->GetSupportedDisplayRefreshRates(MapDisplayType(dpy),
                                               (std::vector<uint32_t> *) supportedRefreshRates);
  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isRCSupported(int dispId, bool* supported) {
  // Mask layers can potentially be shown on any display so report RC supported on all displays if
  // the property enables the feature for use.
  int val = false;  // Default value.
  sdm::Debug::GetProperty(ENABLE_ROUNDED_CORNER, &val);
  *supported = val ? true: false;

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::controlIdleStatusCallback(bool enable) {
  if (enable) {
    hwc_session_->idle_callback_ = callback_;
  } else {
    hwc_session_->idle_callback_.reset();
  }

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::isSupportedConfigSwitch(int dispId, int config, bool* supported) {
  if (!hwc_session_) {
    ALOGW("%s: Invalid hwc session:%p found.", __FUNCTION__, hwc_session_);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  int disp_idx = hwc_session_->GetDisplayIndex(dispId);
  if (disp_idx == -1) {
    ALOGW("%s: Invalid display = %d", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  SCOPE_LOCK(hwc_session_->locker_[disp_idx]);
  if (!hwc_session_->hwc_display_[disp_idx]) {
    ALOGW("%s: Display %d is not connected.", __FUNCTION__, dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  *supported = hwc_session_->hwc_display_[disp_idx]->IsModeSwitchAllowed(config);
  return ScopedAStatus::ok();
}

DisplayType GetDisplayConfigDisplayType(int qdutils_disp_type) {
  switch (qdutils_disp_type) {
    case qdutils::DISPLAY_PRIMARY:
      return DisplayType::PRIMARY;

    case qdutils::DISPLAY_EXTERNAL:
      return DisplayType::EXTERNAL;

    case qdutils::DISPLAY_VIRTUAL:
      return DisplayType::VIRTUAL;

    case qdutils::DISPLAY_BUILTIN_2:
      return DisplayType::BUILTIN2;

    default:
      return DisplayType::INVALID;
  }
}

int DisplayConfigAIDL::GetDispTypeFromPhysicalId(uint64_t physical_disp_id,
                                                 DisplayType *disp_type) {
  // TODO(user): Least significant 8 bit is port id based on the SF current implementaion. Need to
  // revisit this if there is a change in logic to create physical display id in SF.
  int port_id = (physical_disp_id & 0xFF);
  int out_port = 0;
  for (int dpy = qdutils::DISPLAY_PRIMARY; dpy <= qdutils::DISPLAY_EXTERNAL_2; dpy++) {
    int ret = hwc_session_->GetDisplayPortId(dpy, &out_port);
    if (ret != 0){
      return ret;
    }
    if (port_id == out_port) {
      *disp_type = GetDisplayConfigDisplayType(dpy);
      return 0;
    }
  }

  return -ENODEV;
}

ScopedAStatus DisplayConfigAIDL::getDisplayType(long physicalDispId, DisplayType* displayType) {
  if (!displayType) {
    ALOGW("%s: Display type provided is invalid.", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  GetDispTypeFromPhysicalId(physicalDispId, displayType);
  return ScopedAStatus::ok();
}

ScopedAStatus
    DisplayConfigAIDL::setCWBOutputBuffer(const std::shared_ptr<IDisplayConfigCallback>& callback,
                                          int32_t dispId, const Rect& rect, bool postProcessed,
                                          const NativeHandle& buffer) {
  if (!callback_.lock()) {
    ALOGE("%s: Callback_ has not yet been initialized.", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  // Output buffer dump is not supported, if Virtual display is present.
  int dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_VIRTUAL);
  if ((dpy_index != -1) && hwc_session_->hwc_display_[dpy_index]) {
    ALOGW("Output buffer dump is not supported with Virtual display!");
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  hwc2_display_t disp_type = HWC_DISPLAY_PRIMARY;
  if (dispId == UINT32(DisplayType::PRIMARY)) {
    dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_PRIMARY);
  } else if (dispId == UINT32(DisplayType::EXTERNAL)) {
    dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_EXTERNAL);
    disp_type = HWC_DISPLAY_EXTERNAL;
  } else if (dispId == UINT32(DisplayType::BUILTIN2)) {
    dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_BUILTIN_2);
    disp_type = HWC_DISPLAY_BUILTIN_2;
  } else {
    ALOGE("%s: CWB is supported on primary or external display only at present.", __FUNCTION__);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  if (dpy_index == -1) {
    ALOGW("Unable to retrieve display index for display:%d", dispId);
    return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
  }

  // Mutex scope
  {
    SCOPE_LOCK(hwc_session_->locker_[disp_type]);
    if (!hwc_session_->hwc_display_[dpy_index]) {
      ALOGE("%s: Display is not created yet.", __FUNCTION__);
      return ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
    }
  }

  sdm::CwbConfig cwb_config = {};
  cwb_config.tap_point = static_cast<sdm::CwbTapPoint>(postProcessed);
  sdm::LayerRect &roi = cwb_config.cwb_roi;
  roi.left = FLOAT(rect.left);
  roi.top = FLOAT(rect.top);
  roi.right = FLOAT(rect.right);
  roi.bottom = FLOAT(rect.bottom);

  ALOGI("CWB config passed by cwb_client : tappoint %d  CWB_ROI : (%f %f %f %f)",
        cwb_config.tap_point, roi.left, roi.top, roi.right, roi.bottom);

  // TODO(user): Convert NativeHandle to native_handle_t, call PostBuffer
  hwc_session_->cwb_.PostBuffer(callback_, cwb_config, ::android::dupFromAidl(buffer), disp_type);

  return ScopedAStatus::ok();
}

ScopedAStatus DisplayConfigAIDL::setCameraSmoothInfo(CameraSmoothOp op, int32_t fps) {
  int ret = -1;

  if (fps < 0) {
    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  }

  ret = hwc_session_->SetCameraSmoothInfo(op, fps);

  return ret == 0 ? ScopedAStatus::ok() : ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
}

ScopedAStatus DisplayConfigAIDL::registerCallback(
                                const std::shared_ptr<IDisplayConfigCallback>& callback,
                                int64_t* client_handle) {
  int ret = -1;

  if (callback == nullptr) {
    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  }

  ret = hwc_session_->RegisterCallbackClient(callback, client_handle);

  return ret == 0 ? ScopedAStatus::ok() : ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
}

ScopedAStatus DisplayConfigAIDL::unRegisterCallback(int64_t client_handle) {
  int ret = -1;

  if (client_handle < 0) {
    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  }

  ret = hwc_session_->UnregisterCallbackClient(client_handle);

  return ret == 0 ? ScopedAStatus::ok() : ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
}

} // namespace config
} // namespace display
} // namespace hardware
} // namespace qti
} // namespace vendor
} // namespace aidl
