/*
* Copyright (c) 2017-2021, The Linux Foundation. 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.
*/

/*
* Changes from Qualcomm Innovation Center are provided under the following license:
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
*      contributors may be used to endorse or promote products derived
*      from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <core/buffer_allocator.h>
#include <utils/debug.h>
#include <utils/constants.h>
#include <sync/sync.h>
#include <vector>
#include <string>
#include <QtiGralloc.h>

#include "hwc_buffer_sync_handler.h"
#include "hwc_session.h"
#include "hwc_debugger.h"

#define __CLASS__ "HWCSession"

namespace sdm {

void HWCSession::StartServices() {
  int error = DisplayConfig::DeviceInterface::RegisterDevice(this);
  if (error) {
    DLOGW("Could not register IDisplayConfig as service (%d).", error);
  } else {
    DLOGI("IDisplayConfig service registration completed.");
  }
}

int MapDisplayType(DispType dpy) {
  switch (dpy) {
    case DispType::kPrimary:
      return qdutils::DISPLAY_PRIMARY;

    case DispType::kExternal:
      return qdutils::DISPLAY_EXTERNAL;

    case DispType::kVirtual:
      return qdutils::DISPLAY_VIRTUAL;

    case DispType::kBuiltIn2:
      return qdutils::DISPLAY_BUILTIN_2;

    default:
      break;
  }

  return -EINVAL;
}

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));
}

HWCDisplay::DisplayStatus MapExternalStatus(DisplayConfig::ExternalStatus status) {
  switch (status) {
    case DisplayConfig::ExternalStatus::kOffline:
      return HWCDisplay::kDisplayStatusOffline;

    case DisplayConfig::ExternalStatus::kOnline:
      return HWCDisplay::kDisplayStatusOnline;

    case DisplayConfig::ExternalStatus::kPause:
      return HWCDisplay::kDisplayStatusPause;

    case DisplayConfig::ExternalStatus::kResume:
      return HWCDisplay::kDisplayStatusResume;

    default:
      break;
  }

  return HWCDisplay::kDisplayStatusInvalid;
}

int HWCSession::RegisterClientContext(std::shared_ptr<DisplayConfig::ConfigCallback> callback,
                                      DisplayConfig::ConfigInterface **intf) {
  if (!intf) {
    DLOGE("Invalid DisplayConfigIntf location");
    return -EINVAL;
  }

  std::weak_ptr<DisplayConfig::ConfigCallback> wp_callback = callback;
  DisplayConfigImpl *impl = new DisplayConfigImpl(wp_callback, this);
  *intf = impl;

  return 0;
}

void HWCSession::UnRegisterClientContext(DisplayConfig::ConfigInterface *intf) {
  delete static_cast<DisplayConfigImpl *>(intf);
}

HWCSession::DisplayConfigImpl::DisplayConfigImpl(
                               std::weak_ptr<DisplayConfig::ConfigCallback> callback,
                               HWCSession *hwc_session) {
  callback_ = callback;
  hwc_session_ = hwc_session;
}

int HWCSession::DisplayConfigImpl::IsDisplayConnected(DispType dpy, bool *connected) {
  int disp_id = MapDisplayType(dpy);
  int disp_idx = hwc_session_->GetDisplayIndex(disp_id);

  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  } else {
    SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_idx]);
    *connected = hwc_session_->hwc_display_[disp_idx];
  }

  return 0;
}

int HWCSession::SetDisplayStatus(int disp_id, HWCDisplay::DisplayStatus status) {
  int disp_idx = GetDisplayIndex(disp_id);
  int err = -EINVAL;
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  if (disp_idx == qdutils::DISPLAY_PRIMARY) {
    DLOGE("Not supported for this display");
    return err;
  }

  {
    SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
    if (!hwc_display_[disp_idx]) {
      DLOGW("Display is not connected");
      return err;
    }
    DLOGI("Display = %d, Status = %d", disp_idx, status);
    err = hwc_display_[disp_idx]->SetDisplayStatus(status);
    if (err != 0) {
      return err;
    }
  }

  if (status == HWCDisplay::kDisplayStatusResume || status == HWCDisplay::kDisplayStatusPause) {
    hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
    if (active_builtin_disp_id < HWCCallbacks::kNumRealDisplays) {
      callbacks_.Refresh(active_builtin_disp_id);
    }
  }

  return err;
}

int HWCSession::DisplayConfigImpl::SetDisplayStatus(DispType dpy,
                                                    DisplayConfig::ExternalStatus status) {
  return hwc_session_->SetDisplayStatus(MapDisplayType(dpy), MapExternalStatus(status));
}

int HWCSession::DisplayConfigImpl::ConfigureDynRefreshRate(DisplayConfig::DynRefreshRateOp op,
                                                           uint32_t refresh_rate) {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]);
  HWCDisplay *hwc_display = hwc_session_->hwc_display_[HWC_DISPLAY_PRIMARY];

  if (!hwc_display) {
    DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
    return -EINVAL;
  }

  switch (op) {
    case DisplayConfig::DynRefreshRateOp::kDisableMetadata:
      return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, false);

    case DisplayConfig::DynRefreshRateOp::kEnableMetadata:
      return hwc_display->Perform(HWCDisplayBuiltIn::SET_METADATA_DYN_REFRESH_RATE, true);

    case DisplayConfig::DynRefreshRateOp::kSetBinder:
      return hwc_display->Perform(HWCDisplayBuiltIn::SET_BINDER_DYN_REFRESH_RATE, refresh_rate);

    default:
      DLOGW("Invalid operation %d", op);
      return -EINVAL;
  }

  return 0;
}

int HWCSession::GetConfigCount(int disp_id, uint32_t *count) {
  int disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);

  if (hwc_display_[disp_idx]) {
    return hwc_display_[disp_idx]->GetDisplayConfigCount(count);
  }

  return -EINVAL;
}

int HWCSession::DisplayConfigImpl::GetConfigCount(DispType dpy, uint32_t *count) {
  return hwc_session_->GetConfigCount(MapDisplayType(dpy), count);
}

int HWCSession::GetActiveConfigIndex(int disp_id, uint32_t *config) {
  int disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);

  if (hwc_display_[disp_idx]) {
    return hwc_display_[disp_idx]->GetActiveDisplayConfig(config);
  }

  return -EINVAL;
}

int HWCSession::DisplayConfigImpl::GetActiveConfig(DispType dpy, uint32_t *config) {
  return hwc_session_->GetActiveConfigIndex(MapDisplayType(dpy), config);
}

int HWCSession::SetActiveConfigIndex(int disp_id, uint32_t config) {
  int disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
  int error = -EINVAL;
  if (hwc_display_[disp_idx]) {
    error = hwc_display_[disp_idx]->SetActiveDisplayConfig(config);
    if (!error) {
      callbacks_.Refresh(0);
    }
  }

  return error;
}

int HWCSession::SetNoisePlugInOverride(int32_t disp_id, bool override_en, int32_t attn,
                                       int32_t noise_zpos) {
  int32_t disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
  int32_t error = -EINVAL;
  if (hwc_display_[disp_idx]) {
    error = hwc_display_[disp_idx]->SetNoisePlugInOverride(override_en, attn, noise_zpos);
  }

  return error;
}

int HWCSession::DisplayConfigImpl::SetActiveConfig(DispType dpy, uint32_t config) {
  return hwc_session_->SetActiveConfigIndex(MapDisplayType(dpy), config);
}

int HWCSession::DisplayConfigImpl::GetDisplayAttributes(uint32_t config_index, DispType dpy,
                                                        DisplayConfig::Attributes *attributes) {
  int error = -EINVAL;
  int disp_id = MapDisplayType(dpy);
  int disp_idx = hwc_session_->GetDisplayIndex(disp_id);

  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
  } else {
    SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_idx]);
    if (hwc_session_->hwc_display_[disp_idx]) {
      DisplayConfigVariableInfo var_info;
      error = hwc_session_->hwc_display_[disp_idx]->GetDisplayAttributesForConfig(INT(config_index),
                                                                                  &var_info);
      if (!error) {
        attributes->vsync_period = var_info.vsync_period_ns;
        attributes->x_res = var_info.x_pixels;
        attributes->y_res = var_info.y_pixels;
        attributes->x_dpi = var_info.x_dpi;
        attributes->y_dpi = var_info.y_dpi;
        attributes->panel_type = DisplayConfig::DisplayPortType::kDefault;
        attributes->is_yuv = var_info.is_yuv;
      }
    }
  }

  return error;
}

int HWCSession::DisplayConfigImpl::SetPanelBrightness(uint32_t level) {
  if (!(0 <= level && level <= 255)) {
    return -EINVAL;
  }

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

int HWCSession::DisplayConfigImpl::GetPanelBrightness(uint32_t *level) {
  float brightness = -1.0f;
  int error = -EINVAL;

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

  return error;
}

int HWCSession::MinHdcpEncryptionLevelChanged(int disp_id, uint32_t min_enc_level) {
  DLOGI("Display %d", disp_id);

  // SSG team hardcoded disp_id as external because it applies to external only but SSG team sends
  // this level irrespective of external connected or not. So to honor the call, make disp_id to
  // primary & set level.
  disp_id = HWC_DISPLAY_PRIMARY;
  int disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
  HWCDisplay *hwc_display = hwc_display_[disp_idx];
  if (!hwc_display) {
    DLOGE("Display = %d is not connected.", disp_idx);
    return -EINVAL;
  }

  return hwc_display->OnMinHdcpEncryptionLevelChange(min_enc_level);
}

int HWCSession::DisplayConfigImpl::MinHdcpEncryptionLevelChanged(DispType dpy,
                                                                 uint32_t min_enc_level) {
  return hwc_session_->MinHdcpEncryptionLevelChanged(MapDisplayType(dpy), min_enc_level);
}

int HWCSession::DisplayConfigImpl::RefreshScreen() {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]);
  hwc_session_->callbacks_.Refresh(HWC_DISPLAY_PRIMARY);
  return 0;
}

int HWCSession::ControlPartialUpdate(int disp_id, bool enable) {
  int disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  if (disp_idx != HWC_DISPLAY_PRIMARY) {
    DLOGW("CONTROL_PARTIAL_UPDATE is not applicable for display = %d", disp_idx);
    return -EINVAL;
  }
  {
    SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
    HWCDisplay *hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
    if (!hwc_display) {
      DLOGE("primary display object is not instantiated");
      return -EINVAL;
    }

    uint32_t pending = 0;
    DisplayError hwc_error = hwc_display->ControlPartialUpdate(enable, &pending);
    if (hwc_error == kErrorNone) {
      if (!pending) {
        return 0;
      }
    } else if (hwc_error == kErrorNotSupported) {
      return 0;
    } else {
      return -EINVAL;
    }
  }

  // Todo(user): Unlock it before sending events to client. It may cause deadlocks in future.
  // Wait until partial update control is complete
  int error = WaitForCommitDone(HWC_DISPLAY_PRIMARY, kClientPartialUpdate);
  if (error != 0) {
    DLOGW("%s Partial update failed with error %d", enable ? "Enable" : "Disable", error);
  }

  return error;
}

int HWCSession::DisplayConfigImpl::ControlPartialUpdate(DispType dpy, bool enable) {
  return hwc_session_->ControlPartialUpdate(MapDisplayType(dpy), enable);
}

int HWCSession::ToggleScreenUpdate(bool on) {
  hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();

  if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
    DLOGE("No active displays");
    return -EINVAL;
  }
  SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);

  int error = -EINVAL;
  if (hwc_display_[active_builtin_disp_id]) {
    error = hwc_display_[active_builtin_disp_id]->ToggleScreenUpdates(on);
    if (error) {
      DLOGE("Failed to toggle screen updates = %d. Display = %" PRIu64 ", Error = %d", on,
          active_builtin_disp_id, error);
    }
  } else {
    DLOGW("Display = %" PRIu64 " is not connected.", active_builtin_disp_id);
  }

  return error;
}

int HWCSession::DisplayConfigImpl::ToggleScreenUpdate(bool on) {
  return hwc_session_->ToggleScreenUpdate(on);
}

int HWCSession::SetIdleTimeout(uint32_t value) {
  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);

  int inactive_ms = IDLE_TIMEOUT_INACTIVE_MS;
  Debug::Get()->GetProperty(IDLE_TIME_INACTIVE_PROP, &inactive_ms);
  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
    hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(value, inactive_ms);
    idle_time_inactive_ms_ = inactive_ms;
    idle_time_active_ms_ = value;
    return 0;
  }

  DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
  return -ENODEV;
}

int HWCSession::DisplayConfigImpl::SetIdleTimeout(uint32_t value) {
  return hwc_session_->SetIdleTimeout(value);
}

int HWCSession::DisplayConfigImpl::GetHDRCapabilities(DispType dpy,
                                                      DisplayConfig::HDRCapsParams *caps) {
  int error = -EINVAL;

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

    SCOPE_LOCK(hwc_session_->locker_[disp_id]);
    HWCDisplay *hwc_display = hwc_session_->hwc_display_[disp_idx];
    if (!hwc_display) {
      DLOGW("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->supported_hdr_types.resize(out_num_types);

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

  return error;
}

int HWCSession::SetCameraLaunchStatus(uint32_t on) {
  if (null_display_mode_) {
    return 0;
  }

  if (!core_intf_) {
    DLOGW("core_intf_ not initialized.");
    return -ENOENT;
  }

  HWBwModes mode = on > 0 ? kBwVFEOn : kBwVFEOff;

  if (core_intf_->SetMaxBandwidthMode(mode) != kErrorNone) {
    return -EINVAL;
  }

  // trigger invalidate to apply new bw caps.
  callbacks_.Refresh(0);

  return 0;
}

int HWCSession::DisplayConfigImpl::SetCameraLaunchStatus(uint32_t on) {
  return hwc_session_->SetCameraLaunchStatus(on);
}

int HWCSession::DisplayBWTransactionPending(bool *status) {
  SEQUENCE_WAIT_SCOPE_LOCK(locker_[HWC_DISPLAY_PRIMARY]);

  if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
    if (sync_wait(bw_mode_release_fd_, 0) < 0) {
      DLOGI("bw_transaction_release_fd is not yet signaled: err= %s", strerror(errno));
      *status = false;
    }

    return 0;
  }

  DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
  return -ENODEV;
}

int HWCSession::DisplayConfigImpl::DisplayBWTransactionPending(bool *status) {
  return hwc_session_->DisplayBWTransactionPending(status);
}

int HWCSession::ControlIdlePowerCollapse(bool enable, bool synchronous) {
  hwc2_display_t active_builtin_disp_id = GetActiveBuiltinDisplay();
  if (active_builtin_disp_id >= HWCCallbacks::kNumDisplays) {
    DLOGE("No active displays");
    return -EINVAL;
  }
  bool needs_refresh = false;
  {
    SEQUENCE_WAIT_SCOPE_LOCK(locker_[active_builtin_disp_id]);
    if (hwc_display_[active_builtin_disp_id]) {
      if (!enable) {
        if (!idle_pc_ref_cnt_) {
          auto err = hwc_display_[active_builtin_disp_id]->ControlIdlePowerCollapse(enable,
                                                                                    synchronous);
          if (err != kErrorNone) {
            return (err == kErrorNotSupported) ? 0 : -EINVAL;
          }
          needs_refresh = true;
        }
        idle_pc_ref_cnt_++;
      } else if (idle_pc_ref_cnt_ > 0) {
        if (!(idle_pc_ref_cnt_ - 1)) {
          auto err = hwc_display_[active_builtin_disp_id]->ControlIdlePowerCollapse(enable,
                                                                                    synchronous);
          if (err != kErrorNone) {
            return (err == kErrorNotSupported) ? 0 : -EINVAL;
          }
        }
        idle_pc_ref_cnt_--;
      }
    } else {
      DLOGW("Display = %d is not connected.", UINT32(active_builtin_disp_id));
      return -ENODEV;
    }
  }
  if (needs_refresh) {
    int ret = WaitForCommitDone(active_builtin_disp_id, kClientIdlepowerCollapse);
    if (ret != 0) {
      DLOGW("%s Idle PC failed with error %d", enable ? "Enable" : "Disable", ret);
      return -EINVAL;
    }
  }

  DLOGI("Idle PC %s!!", enable ? "enabled" : "disabled");
  return 0;
}

int HWCSession::DisplayConfigImpl::ControlIdlePowerCollapse(bool enable, bool synchronous) {
  return hwc_session_->ControlIdlePowerCollapse(enable, synchronous);
}

int HWCSession::IsWbUbwcSupported(bool *value) {
  HWDisplaysInfo hw_displays_info = {};
  DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
  if (error != kErrorNone) {
    return -EINVAL;
  }

  for (auto &iter : hw_displays_info) {
    auto &info = iter.second;
    if (info.display_type == kVirtual && info.is_wb_ubwc_supported) {
      *value = 1;
    }
  }

  return error;
}

int32_t HWCSession::getDisplayBrightness(uint32_t display, float *brightness) {
  if (!brightness) {
    return HWC2_ERROR_BAD_PARAMETER;
  }

  if (display >= HWCCallbacks::kNumDisplays) {
    return HWC2_ERROR_BAD_DISPLAY;
  }

  SEQUENCE_WAIT_SCOPE_LOCK(locker_[display]);
  int32_t error = -EINVAL;
  *brightness = -1.0f;

  HWCDisplay *hwc_display = hwc_display_[display];
  if (hwc_display && hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
    error = INT32(hwc_display_[display]->GetPanelBrightness(brightness));
    if (error) {
      DLOGE("Failed to get the panel brightness. Error = %d", error);
    }
  }

  return error;
}

int32_t HWCSession::getDisplayMaxBrightness(uint32_t display, uint32_t *max_brightness_level) {
  if (!max_brightness_level) {
    return HWC2_ERROR_BAD_PARAMETER;
  }

  if (display >= HWCCallbacks::kNumDisplays) {
    return HWC2_ERROR_BAD_DISPLAY;
  }

  int32_t error = -EINVAL;
  HWCDisplay *hwc_display = hwc_display_[display];
  if (hwc_display && hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN) {
    error = INT32(hwc_display_[display]->GetPanelMaxBrightness(max_brightness_level));
    if (error) {
      DLOGE("Failed to get the panel max brightness, display %u error %d", display, error);
    }
  }

  return error;
}

int HWCSession::SetCameraSmoothInfo(CameraSmoothOp op, int32_t fps) {
  std::lock_guard<decltype(callbacks_lock_)> lock_guard(callbacks_lock_);
  for (auto const& [id, callback] : callback_clients_) {
    if (callback) {
      callback->notifyCameraSmoothInfo(op, fps);
    }
  }

  return 0;
}

int HWCSession::NotifyResolutionChange(int32_t disp_id, Attributes& attr) {
  std::lock_guard<decltype(callbacks_lock_)> lock_guard(callbacks_lock_);
  for (auto const& [id, callback] : callback_clients_) {
    if (callback) {
      callback->notifyResolutionChange(disp_id, attr);
    }
  }

  return 0;
}

int HWCSession::RegisterCallbackClient(
        const std::shared_ptr<IDisplayConfigCallback>& callback, int64_t *client_handle) {
  std::lock_guard<decltype(callbacks_lock_)> lock_guard(callbacks_lock_);
  callback_clients_.emplace(callback_client_id_, callback);
  *client_handle = callback_client_id_;
  callback_client_id_++;

  return 0;
}

int HWCSession::UnregisterCallbackClient(const int64_t client_handle) {
  bool removed = false;

  std::lock_guard<decltype(callbacks_lock_)> lock_guard(callbacks_lock_);
  for(auto it = callback_clients_.begin(); it != callback_clients_.end(); ) {
    if (it->first == client_handle) {
      it = callback_clients_.erase(it);
      removed = true;
    } else {
      it++;
    }
  }

  return removed ? 0 : -EINVAL;
}

int HWCSession::DisplayConfigImpl::SetDisplayAnimating(uint64_t display_id, bool animating) {
  return hwc_session_->CallDisplayFunction(display_id, &HWCDisplay::SetDisplayAnimating, animating);
}

int HWCSession::DisplayConfigImpl::GetWriteBackCapabilities(bool *isWbUbwcSupported) {
  return hwc_session_->IsWbUbwcSupported(isWbUbwcSupported);
}

int HWCSession::SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start,
                                    uint32_t h_end, uint32_t v_start, uint32_t v_end,
                                    uint32_t factor_in, uint32_t factor_out) {
  return CallDisplayFunction(display_id,
                             &HWCDisplay::SetDisplayDppsAdROI, h_start, h_end, v_start, v_end,
                             factor_in, factor_out);
}

int HWCSession::DisplayConfigImpl::SetDisplayDppsAdROI(uint32_t display_id, uint32_t h_start,
                                                       uint32_t h_end, uint32_t v_start,
                                                       uint32_t v_end, uint32_t factor_in,
                                                       uint32_t factor_out) {
  return hwc_session_->SetDisplayDppsAdROI(display_id, h_start, h_end, v_start, v_end,
                                           factor_in, factor_out);
}

int HWCSession::DisplayConfigImpl::UpdateVSyncSourceOnPowerModeOff() {
  hwc_session_->update_vsync_on_power_off_ = true;
  return 0;
}

int HWCSession::DisplayConfigImpl::UpdateVSyncSourceOnPowerModeDoze() {
  hwc_session_->update_vsync_on_doze_ = true;
  return 0;
}

int HWCSession::DisplayConfigImpl::IsPowerModeOverrideSupported(uint32_t disp_id,
                                                                bool *supported) {
  if (!hwc_session_->async_powermode_ || (disp_id > HWCCallbacks::kNumRealDisplays)) {
    *supported = false;
  } else {
    *supported = true;
  }

  return 0;
}

int HWCSession::DisplayConfigImpl::SetPowerMode(uint32_t disp_id,
                                                DisplayConfig::PowerMode power_mode) {
  SCOPE_LOCK(hwc_session_->display_config_locker_);

  bool supported = false;
  IsPowerModeOverrideSupported(disp_id, &supported);
  if (!supported) {
    return 0;
  }
  // Added this flag for pixel
  hwc_session_->async_power_mode_triggered_  = true;
  // Active builtin display needs revalidation
  hwc2_display_t active_builtin_disp_id = hwc_session_->GetActiveBuiltinDisplay();
  HWC2::PowerMode previous_mode = hwc_session_->hwc_display_[disp_id]->GetCurrentPowerMode();

  DLOGI("disp_id: %d power_mode: %d", disp_id, power_mode);
  auto mode = static_cast<HWC2::PowerMode>(power_mode);

  HWCDisplay::HWCLayerStack stack = {};
  hwc2_display_t dummy_disp_id = hwc_session_->map_hwc_display_.at(disp_id);

  // Power state transition start.
  // Acquire the display's power-state transition var read lock.
  hwc_session_->power_state_[disp_id].Lock();
  hwc_session_->power_state_transition_[disp_id] = true;
  hwc_session_->locker_[disp_id].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_[disp_id]->GetLayerStack(&stack);
  hwc_session_->hwc_display_[dummy_disp_id]->SetLayerStack(&stack);
  hwc_session_->hwc_display_[dummy_disp_id]->UpdatePowerMode(
                                       hwc_session_->hwc_display_[disp_id]->GetCurrentPowerMode());

  buffer_handle_t target = 0;
  shared_ptr<Fence> acquire_fence = nullptr;
  int32_t dataspace = 0;
  hwc_region_t damage = {};
  hwc_session_->hwc_display_[disp_id]->GetClientTarget(
                                 target, acquire_fence, dataspace, damage);
  hwc_session_->hwc_display_[dummy_disp_id]->SetClientTarget(
                                       target, acquire_fence, dataspace, damage);

  // Initialize the variable config map of dummy display using map of real display.
  // Pass the real display's last active config index to dummy display.
  std::map<uint32_t, DisplayConfigVariableInfo> variable_config_map;
  int active_config_index = -1;
  uint32_t num_configs = 0;
  hwc_session_->hwc_display_[disp_id]->GetConfigInfo(&variable_config_map, &active_config_index,
                                                     &num_configs);
  hwc_session_->hwc_display_[dummy_disp_id]->SetConfigInfo(variable_config_map,
                                                           active_config_index, num_configs);

  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_[disp_id].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_[disp_id]->SetPowerMode(mode, false /* teardown */);

  // Power state transition end.
  // Acquire the display's power-state transition var read lock.
  hwc_session_->power_state_[disp_id].Lock();
  hwc_session_->power_state_transition_[disp_id] = 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_[disp_id]->SetLayerStack(&stack);
  bool vsync_pending = hwc_session_->hwc_display_[dummy_disp_id]->VsyncEnablePending();
  if (vsync_pending) {
    hwc_session_->hwc_display_[disp_id]->SetVsyncEnabled(HWC2::Vsync::Enable);
  }
  hwc_session_->hwc_display_[dummy_disp_id]->GetClientTarget(
                                       target, acquire_fence, dataspace, damage);
  hwc_session_->hwc_display_[disp_id]->SetClientTarget(
                                 target, acquire_fence, dataspace, damage);

  // Read display has got layerstack. Update the fences.
  hwc_session_->hwc_display_[disp_id]->PostPowerMode();

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

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

  return 0;
}

int HWCSession::DisplayConfigImpl::IsHDRSupported(uint32_t disp_id, bool *supported) {
  if (disp_id < 0 || disp_id >= HWCCallbacks::kNumDisplays) {
    DLOGE("Not valid display");
    return -EINVAL;
  }
  SCOPE_LOCK(hwc_session_->hdr_locker_[disp_id]);

  if (hwc_session_->is_hdr_display_.size() <= disp_id) {
    DLOGW("is_hdr_display_ is not initialized for display %d!! Reporting it as HDR not supported",
          disp_id);
    *supported = false;
    return 0;
  }

  *supported = static_cast<bool>(hwc_session_->is_hdr_display_[disp_id]);
  return 0;
}

int HWCSession::DisplayConfigImpl::IsWCGSupported(uint32_t disp_id, bool *supported) {
  // todo(user): Query wcg from sdm. For now assume them same.
  return IsHDRSupported(disp_id, supported);
}

int HWCSession::DisplayConfigImpl::SetLayerAsMask(uint32_t disp_id, uint64_t layer_id) {
  SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  HWCDisplay *hwc_display = hwc_session_->hwc_display_[disp_id];
  if (!hwc_display) {
    DLOGW("Display = %d is not connected.", disp_id);
    return -EINVAL;
  }

  if (hwc_session_->disable_mask_layer_hint_) {
    DLOGW("Mask layer hint is disabled!");
    return -EINVAL;
  }

  auto hwc_layer = hwc_display->GetHWCLayer(layer_id);
  if (hwc_layer == nullptr) {
    return -EINVAL;
  }

  hwc_layer->SetLayerAsMask();

  return 0;
}

int HWCSession::DisplayConfigImpl::GetDebugProperty(const std::string prop_name,
                                                    std::string *value) {
  std::string vendor_prop_name = DISP_PROP_PREFIX;
  int error = -EINVAL;
  char val[64] = {};

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

  return error;
}

int HWCSession::DisplayConfigImpl::GetActiveBuiltinDisplayAttributes(
                                                    DisplayConfig::Attributes *attr) {
  int error = -EINVAL;
  hwc2_display_t disp_id = hwc_session_->GetActiveBuiltinDisplay();

  if (disp_id >= HWCCallbacks::kNumDisplays) {
    DLOGE("Invalid display = %d", UINT32(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) {
        goto err;
      }
      DisplayConfigVariableInfo var_info;
      error = hwc_session_->hwc_display_[disp_id]->GetDisplayAttributesForConfig(INT(config_index),
                                                                                 &var_info);
      if (!error) {
        attr->vsync_period = var_info.vsync_period_ns;
        attr->x_res = var_info.x_pixels;
        attr->y_res = var_info.y_pixels;
        attr->x_dpi = var_info.x_dpi;
        attr->y_dpi = var_info.y_dpi;
        attr->panel_type = DisplayConfig::DisplayPortType::kDefault;
        attr->is_yuv = var_info.is_yuv;
      }
    }
  }

err:
  return error;
}

int HWCSession::DisplayConfigImpl::SetPanelLuminanceAttributes(uint32_t disp_id, float pan_min_lum,
                                                               float pan_max_lum) {
  // currently doing only for virtual display
  if (disp_id != qdutils::DISPLAY_VIRTUAL) {
    return -EINVAL;
  }

  // check for out of range luminance values
  if (pan_min_lum <= 0.0f || pan_min_lum >= 1.0f ||
      pan_max_lum <= 100.0f || pan_max_lum >= 1000.0f) {
    return -EINVAL;
  }

  std::lock_guard<std::mutex> obj(hwc_session_->mutex_lum_);
  hwc_session_->set_min_lum_ = pan_min_lum;
  hwc_session_->set_max_lum_ = pan_max_lum;
  DLOGI("set max_lum %f, min_lum %f", pan_max_lum, pan_min_lum);

  return 0;
}

int HWCSession::DisplayConfigImpl::IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin) {
  if ((hwc_session_->map_info_primary_.client_id == disp_id) &&
      (hwc_session_->map_info_primary_.disp_type == kBuiltIn)) {
    *is_builtin = true;
    return 0;
  }

  for (auto &info : hwc_session_->map_info_builtin_) {
    if (disp_id == info.client_id) {
      *is_builtin = true;
      return 0;
    }
  }

  *is_builtin = false;
  return 0;
}

int HWCSession::DisplayConfigImpl::GetSupportedDSIBitClks(uint32_t disp_id,
                                                          std::vector<uint64_t> *bit_clks) {
  SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  if (!hwc_session_->hwc_display_[disp_id]) {
    return -EINVAL;
  }

  hwc_session_->hwc_display_[disp_id]->GetSupportedDSIClock(bit_clks);
  return 0;
}

int HWCSession::DisplayConfigImpl::GetDSIClk(uint32_t disp_id, uint64_t *bit_clk) {
  SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  if (!hwc_session_->hwc_display_[disp_id]) {
    return -EINVAL;
  }

  hwc_session_->hwc_display_[disp_id]->GetDynamicDSIClock(bit_clk);

  return 0;
}

int HWCSession::DisplayConfigImpl::SetDSIClk(uint32_t disp_id, uint64_t bit_clk) {
  SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  if (!hwc_session_->hwc_display_[disp_id]) {
    return -1;
  }

  return hwc_session_->hwc_display_[disp_id]->SetDynamicDSIClock(bit_clk);
}

int HWCSession::DisplayConfigImpl::SetCWBOutputBuffer(uint32_t disp_id,
                                                      const DisplayConfig::Rect rect,
                                                      bool post_processed,
                                                      const native_handle_t *buffer) {
  if (!callback_.lock()) {
    DLOGE("Callback_ has not yet been initialized.");
    return -1;
  }

  if (!buffer) {
    DLOGE("Buffer is null.");
    return -1;
  }

  if (!hwc_session_) {
    DLOGE("HWC Session is not established!");
    return -1;
  }

  auto err = hwc_session_->CheckWbAvailability();
  if (err != HWC2::Error::None) {
    return -1;
  }

  hwc2_display_t disp_type = HWC_DISPLAY_PRIMARY;
  int dpy_index = -1;
  if (disp_id == UINT32(DisplayConfig::DisplayType::kPrimary)) {
    dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_PRIMARY);
  } else if (disp_id == UINT32(DisplayConfig::DisplayType::kExternal)) {
    dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_EXTERNAL);
    disp_type = HWC_DISPLAY_EXTERNAL;
  } else if (disp_id == UINT32(DisplayConfig::DisplayType::kBuiltIn2)) {
    dpy_index = hwc_session_->GetDisplayIndex(qdutils::DISPLAY_BUILTIN_2);
    disp_type = HWC_DISPLAY_BUILTIN_2;
  } else {
    DLOGE("CWB is supported on primary and external displays only at present.");
    return -1;
  }

  if (dpy_index == -1) {
    DLOGW("Unable to retrieve display index for display:%d", disp_id);
    return -1;
  }

  if (dpy_index >= HWCCallbacks::kNumDisplays) {
    DLOGW("Display index (%d) for display(%d) is out of bound for "
          "maximum displays supported(%d).", dpy_index, disp_id, HWCCallbacks::kNumDisplays);
    return -1;
  }

  // Mutex scope
  {
    SCOPE_LOCK(hwc_session_->locker_[disp_type]);
    if (!hwc_session_->hwc_display_[dpy_index]) {
      DLOGE("Display is not created yet with display index = %d and display id = %d!",
            dpy_index, disp_id);
      return -1;
    }
  }

  CwbConfig cwb_config = {};
  cwb_config.tap_point = static_cast<CwbTapPoint>(post_processed);
  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);

  DLOGI("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);

  return hwc_session_->cwb_.PostBuffer(callback_, cwb_config, native_handle_clone(buffer),
                                       disp_type);
}

int32_t HWCSession::CWB::PostBuffer(std::weak_ptr<DisplayConfig::ConfigCallback> callback,
                                    const CwbConfig &cwb_config, const native_handle_t *buffer,
                                    hwc2_display_t display_type) {
  HWC2::Error error = HWC2::Error::None;
  auto& session_map = display_cwb_session_map_[display_type];
  std::shared_ptr<QueueNode> node = nullptr;
  uint64_t node_handle_id = 0;
  void *hdl = const_cast<native_handle_t *>(buffer);
  auto err = gralloc::GetMetaDataValue(hdl, (int64_t)StandardMetadataType::BUFFER_ID,
                                       &node_handle_id);
  if (err != gralloc::Error::NONE || node_handle_id == 0) {
    error = HWC2::Error::BadLayer;
    DLOGE("Buffer handle id retrieval failed!");
  }

  if (error == HWC2::Error::None) {
    node = std::make_shared<QueueNode>(callback, cwb_config, buffer, display_type, node_handle_id);
    if (node) {
      // Keep CWB request handling related resources in a requested display context.
      std::unique_lock<std::mutex> lock(session_map.lock);

      // Iterate over the queue to avoid duplicate node of same buffer, because that
      // buffer is already present in queue.
      for (auto& qnode : session_map.queue) {
        if (qnode->handle_id == node_handle_id) {
          error = HWC2::Error::BadParameter;
          DLOGW("CWB Buffer with handle id %lu is already available in Queue for processing!",
                node_handle_id);
          break;
        }
      }

      // Ensure that async task runs only until all queued CWB requests have been fulfilled.
      // If cwb queue is empty, async task has not either started or async task has finished
      // processing previously queued cwb requests. Start new async task on such a case as
      // currently running async task will automatically desolve without processing more requests.
      if (error == HWC2::Error::None) {
        session_map.queue.push_back(node);
      }
    } else {
      error = HWC2::Error::BadParameter;
      DLOGE("Unable to allocate node for CWB request(handle id: %lu)!", node_handle_id);
    }
  }

  if (error == HWC2::Error::None) {
    SCOPE_LOCK(hwc_session_->locker_[display_type]);
    // Get display instance using display type.
    HWCDisplay *hwc_display = hwc_session_->hwc_display_[display_type];
    if (!hwc_display) {
      error = HWC2::Error::BadDisplay;
    } else {
      // Send CWB request to CWB Manager
      error = hwc_display->SetReadbackBuffer(buffer, nullptr, cwb_config, kCWBClientExternal);
    }
  }

  if (error == HWC2::Error::None) {
    DLOGV_IF(kTagCwb, "Successfully configured CWB buffer(handle id: %lu).", node_handle_id);
  } else {
    // Need to close and delete the cloned native handle on CWB request rejection/failure and
    // if node is created and pushed, then need to remove from queue.
    native_handle_close(buffer);
    native_handle_delete(const_cast<native_handle_t *>(buffer));
    std::unique_lock<std::mutex> lock(session_map.lock);
    // If current node is pushed in the queue, then need to remove it again on error.
    if (node && node == session_map.queue.back()) {
      session_map.queue.pop_back();
    }
    return -1;
  }

  std::unique_lock<std::mutex> lock(session_map.lock);
  if (!session_map.async_thread_running && !session_map.queue.empty()) {
    session_map.async_thread_running = true;
    // No need to do future.get() here for previously running async task. Async method will
    // guarantee to exit after cwb for all queued requests is indeed complete i.e. the respective
    // fences have signaled and client is notified through registered callbacks. This will make
    // sure that the new async task does not concurrently work with previous task. Let async
    // running thread dissolve on its own.
    // Check, If thread is not running, then need to re-execute the async thread.
    session_map.future = std::async(HWCSession::CWB::AsyncTaskToProcessCWBStatus,
                                    this, display_type);
  }

  if (node) {
    node->request_completed = true;
  }

  return 0;
}


int HWCSession::CWB::OnCWBDone(hwc2_display_t display_type, int32_t status, uint64_t handle_id) {
  auto& session_map = display_cwb_session_map_[display_type];

  {
    std::unique_lock<std::mutex> lock(session_map.lock);
    // No need to notify to the client, if there is no any pending CWB request in queue.
    if (session_map.queue.empty()) {
      return -1;
    }

    for (auto& node : session_map.queue) {
      if (node->notified_status == kCwbNotifiedNone) {
        // Need to wait for other notification, when notified handle id does not match with
        // available first non-notified node buffer handle id in queue.
        if (node->handle_id == handle_id) {
          node->notified_status = (status) ? kCwbNotifiedFailure : kCwbNotifiedSuccess;
          session_map.cv.notify_one();
          return 0;
        } else {
          // Continue to check on not matching handle_id, to update the status of any matching
          // node, because if notification for particular handle_id skip, then it will not update
          // again and notification thread will wait for skipped node forever.
          continue;
        }
      }
    }
  }

  return -1;
}

void HWCSession::CWB::AsyncTaskToProcessCWBStatus(CWB *cwb, hwc2_display_t display_type) {
  cwb->ProcessCWBStatus(display_type);
}

void HWCSession::CWB::ProcessCWBStatus(hwc2_display_t display_type) {
  auto& session_map = display_cwb_session_map_[display_type];
  while(true) {
    std::shared_ptr<QueueNode> cwb_node = nullptr;
    {
      std::unique_lock<std::mutex> lock(session_map.lock);
      // Exit thread in case of no pending CWB request in queue.
      if (session_map.queue.empty()) {
        // Update thread exiting status.
        session_map.async_thread_running = false;
        break;
      }

      cwb_node = session_map.queue.front();
      if (!cwb_node->request_completed) {
        // Need to continue to recheck until node specific client call completes.
        continue;
      } else if (cwb_node->notified_status == kCwbNotifiedNone) {
        // Wait for the signal for availability of CWB notified node.
        session_map.cv.wait(lock);
        if (cwb_node->notified_status == kCwbNotifiedNone) {
          // If any other node notified before front node, then need to continue to wait
          // for front node, such that further client notification will be done in sequential
          // manner.
          DLOGW("CWB request is notified out of sequence.");
          continue;
        }
      }
      session_map.queue.pop_front();
    }

    // Notify to client, when notification is received successfully for expected input buffer.
    NotifyCWBStatus(cwb_node->notified_status , cwb_node);
  }
  DLOGI("CWB queue is empty. Display: %d", display_type);
}

void HWCSession::CWB::NotifyCWBStatus(int status, std::shared_ptr<QueueNode> cwb_node) {
  // Notify client about buffer status and erase the node from pending request queue.
  std::shared_ptr<DisplayConfig::ConfigCallback> callback = cwb_node->callback.lock();
  if (callback) {
    DLOGI("Notify the client about buffer status %d.", status);
    callback->NotifyCWBBufferDone(status, cwb_node->buffer);
  }

  native_handle_close(cwb_node->buffer);
  native_handle_delete(const_cast<native_handle_t *>(cwb_node->buffer));
}

int HWCSession::NotifyCwbDone(hwc2_display_t display, int32_t status, uint64_t handle_id) {
    return cwb_.OnCWBDone(display, status, handle_id);
}

bool HWCSession::CWB::IsCwbActiveOnDisplay(hwc2_display_t disp_type) {
  std::unique_lock<std::mutex> lock(display_cwb_session_map_[disp_type].lock);
  auto &queue = display_cwb_session_map_[disp_type].queue;
  return (queue.size() && (queue.front()->display_type == disp_type)) ? true : false;
}

int HWCSession::DisplayConfigImpl::SetQsyncMode(uint32_t disp_id, DisplayConfig::QsyncMode mode) {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  if (!hwc_session_->hwc_display_[disp_id]) {
    return -1;
  }

  QSyncMode qsync_mode = kQSyncModeNone;
  switch (mode) {
    case DisplayConfig::QsyncMode::kNone:
      qsync_mode = kQSyncModeNone;
      break;
    case DisplayConfig::QsyncMode::kWaitForFencesOneFrame:
      qsync_mode = kQsyncModeOneShot;
      break;
    case DisplayConfig::QsyncMode::kWaitForFencesEachFrame:
      qsync_mode = kQsyncModeOneShotContinuous;
      break;
    case DisplayConfig::QsyncMode::kWaitForCommitEachFrame:
      qsync_mode = kQSyncModeContinuous;
      break;
  }

  hwc_session_->hwc_display_[disp_id]->SetQSyncMode(qsync_mode);
  hwc_session_->hwc_display_qsync_[disp_id]  = qsync_mode;
  return 0;
}

int HWCSession::DisplayConfigImpl::IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id,
                                                      bool *is_smart) {
  SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  if (!hwc_session_->hwc_display_[disp_id]) {
    DLOGE("Display %d is not created yet.", disp_id);
    *is_smart = false;
    return -EINVAL;
  }

  if (hwc_session_->hwc_display_[disp_id]->GetDisplayClass() != DISPLAY_CLASS_BUILTIN) {
    return false;
  }

  *is_smart = hwc_session_->hwc_display_[disp_id]->IsSmartPanelConfig(config_id);
  return 0;
}

int HWCSession::DisplayConfigImpl::IsAsyncVDSCreationSupported(bool *supported) {
  if (!hwc_session_->async_vds_creation_) {
    *supported = false;
    return 0;
  }

  *supported = true;
  return 0;
}

int HWCSession::DisplayConfigImpl::CreateVirtualDisplay(uint32_t width, uint32_t height,
                                                        int32_t format) {
  if (!hwc_session_->async_vds_creation_) {
    return HWC2_ERROR_UNSUPPORTED;
  }

  if (!width || !height) {
    return HWC2_ERROR_BAD_PARAMETER;
  }

  hwc2_display_t active_builtin_disp_id = hwc_session_->GetActiveBuiltinDisplay();
  hwc2_display_t virtual_id;
  auto status = hwc_session_->CreateVirtualDisplayObj(width, height, &format,
                                                      &virtual_id);
  if (status == HWC2::Error::None) {
    DLOGI("[async] Created virtual display id:%" PRIu64 ", res: %dx%d",
          virtual_id, width, height);
    if (active_builtin_disp_id < HWCCallbacks::kNumRealDisplays) {
      hwc_session_->WaitForResources(true, active_builtin_disp_id, virtual_id);
    }
  } else {
    DLOGE("Failed to create virtual display: %s", to_string(status).c_str());
  }

  return INT(status);
}

int HWCSession::DisplayConfigImpl::IsRotatorSupportedFormat(int hal_format, bool ubwc,
                                                             bool *supported) {
  if (!hwc_session_->core_intf_) {
    DLOGW("core_intf_ not initialized.");
    *supported = false;
    return -EINVAL;
  }
  int flag = ubwc ? qtigralloc::PRIV_FLAGS_UBWC_ALIGNED : 0;

  LayerBufferFormat sdm_format = HWCLayer::GetSDMFormat(hal_format, flag);

  *supported = hwc_session_->core_intf_->IsRotatorSupportedFormat(sdm_format);
  return 0;
}

int HWCSession::DisplayConfigImpl::ControlQsyncCallback(bool enable) {
  if (enable) {
    hwc_session_->qsync_callback_ = callback_;
  } else {
    hwc_session_->qsync_callback_.reset();
  }

  return 0;
}

int HWCSession::DisplayConfigImpl::GetDisplayHwId(uint32_t disp_id, uint32_t *display_hw_id) {
  int disp_idx = hwc_session_->GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SCOPE_LOCK(hwc_session_->locker_[disp_id]);
  if (!hwc_session_->hwc_display_[disp_idx]) {
    DLOGW("Display %d is not connected.", disp_id);
    return -EINVAL;
  }

  int error = -EINVAL;
  // Supported for Built-In displays only.
  if ((hwc_session_->map_info_primary_.client_id == disp_id) &&
      (hwc_session_->map_info_primary_.disp_type == kBuiltIn)) {
    if (hwc_session_->map_info_primary_.sdm_id >= 0) {
      *display_hw_id = static_cast<uint32_t>(hwc_session_->map_info_primary_.sdm_id);
      error = 0;
    }
    return error;
  }

  for (auto &info : hwc_session_->map_info_builtin_) {
    if (disp_id == info.client_id) {
      if (info.sdm_id >= 0) {
        *display_hw_id = static_cast<uint32_t>(info.sdm_id);
        error = 0;
      }
      return error;
    }
  }

  return error;
}

int HWCSession::DisplayConfigImpl::SendTUIEvent(DispType dpy,
                                                DisplayConfig::TUIEventType event_type) {
  int disp_id = MapDisplayType(dpy);
  switch(event_type) {
    case DisplayConfig::TUIEventType::kPrepareTUITransition:
      return hwc_session_->TUITransitionPrepare(disp_id);
    case DisplayConfig::TUIEventType::kStartTUITransition:
      return hwc_session_->TUITransitionStart(disp_id);
    case DisplayConfig::TUIEventType::kEndTUITransition:
      return hwc_session_->TUITransitionEnd(disp_id);
    default:
      DLOGE("Invalid event %d", event_type);
      return -EINVAL;
  }
}

int HWCSession::GetSupportedDisplayRefreshRates(int disp_id,
                                                std::vector<uint32_t> *supported_refresh_rates) {
  int disp_idx = GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SCOPE_LOCK(locker_[disp_idx]);

  if (hwc_display_[disp_idx]) {
    return hwc_display_[disp_idx]->GetSupportedDisplayRefreshRates(supported_refresh_rates);
  }
  return -EINVAL;
}

int HWCSession::DisplayConfigImpl::GetSupportedDisplayRefreshRates(
    DispType dpy, std::vector<uint32_t> *supported_refresh_rates) {
  return hwc_session_->GetSupportedDisplayRefreshRates(MapDisplayType(dpy),
                                                       supported_refresh_rates);
}

int HWCSession::DisplayConfigImpl::IsRCSupported(uint32_t disp_id, 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.
  Debug::GetProperty(ENABLE_ROUNDED_CORNER, &val);
  *supported = val ? true: false;

  return 0;
}

int HWCSession::DisplayConfigImpl::IsSupportedConfigSwitch(uint32_t disp_id, uint32_t config,
                                                         bool *supported) {
  int disp_idx = hwc_session_->GetDisplayIndex(disp_id);
  if (disp_idx == -1) {
    DLOGE("Invalid display = %d", disp_id);
    return -EINVAL;
  }

  SCOPE_LOCK(hwc_session_->locker_[disp_idx]);
  if (!hwc_session_->hwc_display_[disp_idx]) {
    DLOGW("Display %d is not connected.", disp_id);
    return -EINVAL;
  }

  *supported = hwc_session_->hwc_display_[disp_idx]->IsModeSwitchAllowed(config);

  return 0;
}

int HWCSession::DisplayConfigImpl::ControlIdleStatusCallback(bool enable) {
  if (enable) {
    hwc_session_->idle_callback_ = callback_;
  } else {
    hwc_session_->idle_callback_.reset();
  }

  return 0;
}

int HWCSession::DisplayConfigImpl::GetDisplayType(uint64_t physical_disp_id, DispType *disp_type) {
  if (!disp_type) {
    return -EINVAL;
  }
  return hwc_session_->GetDispTypeFromPhysicalId(physical_disp_id, disp_type);
}

int HWCSession::DisplayConfigImpl::AllowIdleFallback() {
  SEQUENCE_WAIT_SCOPE_LOCK(hwc_session_->locker_[HWC_DISPLAY_PRIMARY]);

  uint32_t active_ms = 0;
  uint32_t inactive_ms = 0;
  Debug::GetIdleTimeoutMs(&active_ms, &inactive_ms);
  if (hwc_session_->hwc_display_[HWC_DISPLAY_PRIMARY]) {
    DLOGI("enable idle time active_ms:%d inactive_ms:%d",active_ms,inactive_ms);
    hwc_session_->hwc_display_[HWC_DISPLAY_PRIMARY]->SetIdleTimeoutMs(active_ms, inactive_ms);
    hwc_session_->is_client_up_ = true;
    hwc_session_->hwc_display_[HWC_DISPLAY_PRIMARY]->MarkClientActive(true);
    hwc_session_->idle_time_inactive_ms_ = inactive_ms;
    hwc_session_->idle_time_active_ms_ = active_ms;
    return 0;
  }

  DLOGW("Display = %d is not connected.", HWC_DISPLAY_PRIMARY);
  return -ENODEV;
}
}  // namespace sdm
