diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index 9ebba31..6c03722 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -14,283 +14,910 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "drmhwc"
 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
 
 #include "ComposerClient.h"
 
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
 #include <android/binder_ibinder_platform.h>
+#include <hardware/hwcomposer2.h>
+
+#include <cinttypes>
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "aidl/android/hardware/graphics/common/Transform.h"
+#include "aidl/android/hardware/graphics/composer3/ClientTarget.h"
+#include "aidl/android/hardware/graphics/composer3/Composition.h"
+#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
+#include "aidl/android/hardware/graphics/composer3/IComposerClient.h"
+#include "aidl/android/hardware/graphics/composer3/PowerMode.h"
+#include "aidl/android/hardware/graphics/composer3/PresentOrValidate.h"
+#include "aidl/android/hardware/graphics/composer3/RenderIntent.h"
+#include "android/binder_auto_utils.h"
+#include "cutils/native_handle.h"
+#include "hardware/hwcomposer_defs.h"
+#include "hwc2_device/HwcDisplay.h"
+#include "hwc2_device/HwcLayer.h"
+#include "hwc3/DrmHwcThree.h"
+#include "hwc3/Utils.h"
+
+using ::android::HwcDisplay;
 
 #include "utils/log.h"
 
 namespace aidl::android::hardware::graphics::composer3::impl {
+namespace {
 
-// NOLINTNEXTLINE
-#define DEBUG_FUNC() ALOGV("%s", __func__)
+// clang-format off
+constexpr std::array<float, 16> kIdentityMatrix = {
+    1.0F, 0.0F, 0.0F, 0.0F,
+    0.0F, 1.0F, 0.0F, 0.0F,
+    0.0F, 0.0F, 1.0F, 0.0F,
+    0.0F, 0.0F, 0.0F, 1.0F,
+};
+// clang-format on
 
+}  // namespace
+
+ComposerClient::ComposerClient() {
+  DEBUG_FUNC();
+}
+
+bool ComposerClient::Init() {
+  DEBUG_FUNC();
+  composer_resources_ = ComposerResources::Create();
+  if (composer_resources_) {
+    hwc_ = std::make_unique<DrmHwcThree>(composer_resources_.get());
+  }
+  return composer_resources_ != nullptr;
+}
+
+// NOLINTNEXTLINE(bugprone-exception-escape)
 ComposerClient::~ComposerClient() {
   DEBUG_FUNC();
-
   LOG(DEBUG) << "removed composer client";
 }
 
-// no need to check nullptr for output parameter, the aidl stub code won't pass
-// nullptr
-ndk::ScopedAStatus ComposerClient::createLayer(int64_t /*display*/,
-                                               int32_t /*bufferSlotCount*/,
-                                               int64_t* /*layer*/) {
+ndk::ScopedAStatus ComposerClient::createLayer(int64_t display_id,
+                                               int32_t buffer_slot_count,
+                                               int64_t* layer_id) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  hwc2_layer_t hwc2_layer_id = 0;
+  auto err = Hwc2toHwc3Error(display->CreateLayer(&hwc2_layer_id));
+  if (err != hwc3::Error::kNone) {
+    return ToBinderStatus(err);
+  }
+
+  const int64_t created_layer_id = Hwc2LayerToHwc3(hwc2_layer_id);
+  err = composer_resources_->AddLayer(display_id, created_layer_id,
+                                      buffer_slot_count);
+  if (err != hwc3::Error::kNone) {
+    destroyLayer(display_id, created_layer_id);
+    return ToBinderStatus(err);
+  }
+
+  *layer_id = created_layer_id;
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::createVirtualDisplay(
-    int32_t /*width*/, int32_t /*height*/, AidlPixelFormat /*formatHint*/,
-    int32_t /*outputBufferSlotCount*/, VirtualDisplay* /*display*/) {
+    int32_t width, int32_t height, AidlPixelFormat format_hint,
+    int32_t output_buffer_slot_count, VirtualDisplay* out_display) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+
+  hwc2_display_t hwc2_display_id = 0;
+  // TODO: Format is currently not used in drm_hwcomposer.
+  int32_t hwc2_format = 0;
+  auto err = Hwc2toHwc3Error(hwc_->CreateVirtualDisplay(width, height,
+                                                        &hwc2_format,
+                                                        &hwc2_display_id));
+  if (err != hwc3::Error::kNone) {
+    return ToBinderStatus(err);
+  }
+
+  const int64_t created_display_id = Hwc2DisplayToHwc3(hwc2_display_id);
+  err = composer_resources_->AddVirtualDisplay(hwc2_display_id,
+                                               output_buffer_slot_count);
+  if (err != hwc3::Error::kNone) {
+    hwc_->DestroyVirtualDisplay(hwc2_display_id);
+    return ToBinderStatus(err);
+  }
+
+  out_display->display = created_display_id;
+  out_display->format = format_hint;
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t /*display*/,
-                                                int64_t /*layer*/) {
+ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display_id,
+                                                int64_t layer_id) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto err = Hwc2toHwc3Error(display->DestroyLayer(Hwc3LayerToHwc2(layer_id)));
+  if (err != hwc3::Error::kNone) {
+    return ToBinderStatus(err);
+  }
+
+  err = composer_resources_->RemoveLayer(display_id, layer_id);
+  return ToBinderStatus(err);
 }
 
-ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t /*display*/) {
+ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display_id) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  auto err = Hwc2toHwc3Error(hwc_->DestroyVirtualDisplay(display_id));
+  return ToBinderStatus(err);
+}
+
+hwc3::Error ComposerClient::ValidateDisplayInternal(
+    HwcDisplay& display, std::vector<int64_t>* out_changed_layers,
+    std::vector<Composition>* out_composition_types,
+    int32_t* out_display_request_mask,
+    std::vector<int64_t>* out_requested_layers,
+    std::vector<int32_t>* out_request_masks,
+    ClientTargetProperty* /*out_client_target_property*/,
+    DimmingStage* /*out_dimming_stage*/) {
+  DEBUG_FUNC();
+
+  uint32_t num_types = 0;
+  uint32_t num_requests = 0;
+  const HWC2::Error hwc2_error = display.ValidateDisplay(&num_types,
+                                                         &num_requests);
+
+  /* Check if display has pending changes and no errors */
+  if (hwc2_error != HWC2::Error::None &&
+      hwc2_error != HWC2::Error::HasChanges) {
+    return Hwc2toHwc3Error(hwc2_error);
+  }
+
+  std::vector<hwc2_layer_t> hwc_changed_layers(num_types);
+  std::vector<int32_t> hwc_composition_types(num_types);
+  hwc3::Error error = Hwc2toHwc3Error(
+      display.GetChangedCompositionTypes(&num_types, hwc_changed_layers.data(),
+                                         hwc_composition_types.data()));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  int32_t display_reqs = 0;
+  out_request_masks->resize(num_requests);
+  std::vector<hwc2_layer_t> hwc_requested_layers(num_requests);
+  error = Hwc2toHwc3Error(
+      display.GetDisplayRequests(&display_reqs, &num_requests,
+                                 hwc_requested_layers.data(),
+                                 out_request_masks->data()));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  for (const auto& layer : hwc_changed_layers) {
+    out_changed_layers->emplace_back(Hwc2LayerToHwc3(layer));
+  }
+  for (const auto& type : hwc_composition_types) {
+    out_composition_types->emplace_back(Hwc2CompositionTypeToHwc3(type));
+  }
+  for (const auto& layer : hwc_requested_layers) {
+    out_requested_layers->emplace_back(Hwc2LayerToHwc3(layer));
+  }
+  *out_display_request_mask = display_reqs;
+
+  /* Client target property/dimming stage unsupported */
+  return hwc3::Error::kNone;
+}
+
+hwc3::Error ComposerClient::PresentDisplayInternal(
+    uint64_t display_id, ::android::base::unique_fd& out_display_fence,
+    std::unordered_map<int64_t, ::android::base::unique_fd>&
+        out_release_fences) {
+  DEBUG_FUNC();
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return hwc3::Error::kBadDisplay;
+  }
+
+  if (composer_resources_->MustValidateDisplay(display_id)) {
+    return hwc3::Error::kNotValidated;
+  }
+
+  int32_t present_fence = -1;
+  auto error = Hwc2toHwc3Error(display->PresentDisplay(&present_fence));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+  out_display_fence.reset(present_fence);
+
+  uint32_t release_fence_count = 0;
+  error = Hwc2toHwc3Error(
+      display->GetReleaseFences(&release_fence_count, nullptr, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  std::vector<hwc2_layer_t> hwc_layers(release_fence_count);
+  std::vector<int32_t> hwc_fences(release_fence_count);
+  error = Hwc2toHwc3Error(display->GetReleaseFences(&release_fence_count,
+                                                    hwc_layers.data(),
+                                                    hwc_fences.data()));
+  if (error != hwc3::Error::kNone) {
+    return error;
+  }
+
+  for (size_t i = 0; i < hwc_layers.size(); i++) {
+    auto layer = Hwc2LayerToHwc3(hwc_layers[i]);
+    out_release_fences[layer] = ::android::base::unique_fd{hwc_fences[i]};
+  }
+
+  return hwc3::Error::kNone;
+}
+
+::android::HwcDisplay* ComposerClient::GetDisplay(uint64_t display_id) {
+  return hwc_->GetDisplay(display_id);
+}
+
+void ComposerClient::DispatchLayerCommand(int64_t display_id,
+                                          const LayerCommand& command) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto* layer = display->get_layer(command.layer);
+  if (layer == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadLayer);
+    return;
+  }
+
+  HwcLayerWrapper layer_wrapper{command.layer, layer};
+  if (command.buffer) {
+    ExecuteSetLayerBuffer(display_id, layer_wrapper, *command.buffer);
+  }
+  if (command.blendMode) {
+    ExecuteSetLayerBlendMode(display_id, layer_wrapper, *command.blendMode);
+  }
+  if (command.composition) {
+    ExecuteSetLayerComposition(display_id, layer_wrapper, *command.composition);
+  }
+  if (command.dataspace) {
+    ExecuteSetLayerDataspace(display_id, layer_wrapper, *command.dataspace);
+  }
+  if (command.displayFrame) {
+    ExecuteSetLayerDisplayFrame(display_id, layer_wrapper,
+                                *command.displayFrame);
+  }
+  if (command.planeAlpha) {
+    ExecuteSetLayerPlaneAlpha(display_id, layer_wrapper, *command.planeAlpha);
+  }
+  if (command.sourceCrop) {
+    ExecuteSetLayerSourceCrop(display_id, layer_wrapper, *command.sourceCrop);
+  }
+  if (command.transform) {
+    ExecuteSetLayerTransform(display_id, layer_wrapper, *command.transform);
+  }
+  if (command.z) {
+    ExecuteSetLayerZOrder(display_id, layer_wrapper, *command.z);
+  }
+  if (command.brightness) {
+    ExecuteSetLayerBrightness(display_id, layer_wrapper, *command.brightness);
+  }
+
+  // Some unsupported functionality returns kUnsupported, and others
+  // are just a no-op.
+  // TODO: Audit whether some of these should actually return kUnsupported
+  // instead.
+  if (command.sidebandStream) {
+    cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
+  }
+  // TODO: Blocking region handling missing.
+  // TODO: Layer surface damage.
+  // TODO: Layer visible region.
+  // TODO: Per-frame metadata.
+  // TODO: Layer color transform.
+  // TODO: Layer cursor position.
+  // TODO: Layer color.
+}
+
+void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
+  const int64_t display_id = command.display;
+  if (hwc_->GetDisplay(display_id) == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  for (const auto& layer_cmd : command.layers) {
+    DispatchLayerCommand(command.display, layer_cmd);
+  }
+
+  if (command.brightness) {
+    ExecuteSetDisplayBrightness(command.display, *command.brightness);
+  }
+  if (command.colorTransformMatrix) {
+    ExecuteSetDisplayColorTransform(command.display,
+                                    *command.colorTransformMatrix);
+  }
+  if (command.clientTarget) {
+    ExecuteSetDisplayClientTarget(command.display, *command.clientTarget);
+  }
+  if (command.virtualDisplayOutputBuffer) {
+    ExecuteSetDisplayOutputBuffer(command.display,
+                                  *command.virtualDisplayOutputBuffer);
+  }
+  if (command.validateDisplay) {
+    ExecuteValidateDisplay(command.display, command.expectedPresentTime);
+  }
+  if (command.acceptDisplayChanges) {
+    ExecuteAcceptDisplayChanges(command.display);
+  }
+  if (command.presentDisplay) {
+    ExecutePresentDisplay(command.display);
+  }
+  if (command.presentOrValidateDisplay) {
+    ExecutePresentOrValidateDisplay(command.display,
+                                    command.expectedPresentTime);
+  }
 }
 
 ndk::ScopedAStatus ComposerClient::executeCommands(
-    const std::vector<DisplayCommand>& /*commands*/,
-    std::vector<CommandResultPayload>* /*results*/) {
-  DEBUG_FUNC();
+    const std::vector<DisplayCommand>& commands,
+    std::vector<CommandResultPayload>* results) {
+  cmd_result_writer_ = std::make_unique<CommandResultWriter>(results);
+  for (const auto& cmd : commands) {
+    ExecuteDisplayCommand(cmd);
+    cmd_result_writer_->IncrementCommand();
+  }
+  cmd_result_writer_.reset();
+
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t /*display*/,
-                                                   int32_t* /*config*/) {
+ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display_id,
+                                                   int32_t* config) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t hwc2_config = 0;
+  const hwc3::Error error = Hwc2toHwc3Error(
+      display->GetActiveConfig(&hwc2_config));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+  *config = Hwc2ConfigIdToHwc3(hwc2_config);
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getColorModes(
-    int64_t /*display*/, std::vector<ColorMode>* /*colorModes*/) {
+    int64_t display_id, std::vector<ColorMode>* color_modes) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t num_modes = 0;
+  auto error = Hwc2toHwc3Error(display->GetColorModes(&num_modes, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<int32_t> hwc2_color_modes(num_modes);
+  error = Hwc2toHwc3Error(
+      display->GetColorModes(&num_modes, hwc2_color_modes.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  for (const auto& mode : hwc2_color_modes) {
+    color_modes->push_back(Hwc2ColorModeToHwc3(mode));
+  }
+
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(
-    common::Dataspace /*dataspace*/, std::vector<float>* /*matrix*/) {
+    common::Dataspace dataspace, std::vector<float>* matrix) {
   DEBUG_FUNC();
+  if (dataspace != common::Dataspace::SRGB_LINEAR) {
+    return ToBinderStatus(hwc3::Error::kBadParameter);
+  }
+
+  matrix->clear();
+  matrix->insert(matrix->begin(), kIdentityMatrix.begin(),
+                 kIdentityMatrix.end());
+
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayAttribute(
-    int64_t /*display*/, int32_t /*config*/, DisplayAttribute /*attribute*/,
-    int32_t* /*value*/) {
+    int64_t display_id, int32_t config, DisplayAttribute attribute,
+    int32_t* value) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  const hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayAttribute(Hwc3ConfigIdToHwc2(config),
+                                   Hwc3DisplayAttributeToHwc2(attribute),
+                                   value));
+  return ToBinderStatus(error);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(
-    int64_t /*display*/, std::vector<DisplayCapability>* /*caps*/) {
+    int64_t display_id, std::vector<DisplayCapability>* caps) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
 
+  uint32_t num_capabilities = 0;
+  hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayCapabilities(&num_capabilities, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<uint32_t> out_caps(num_capabilities);
+  error = Hwc2toHwc3Error(
+      display->GetDisplayCapabilities(&num_capabilities, out_caps.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  caps->reserve(num_capabilities);
+  for (const auto cap : out_caps) {
+    caps->emplace_back(Hwc2DisplayCapabilityToHwc3(cap));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayConfigs(
-    int64_t /*display*/, std::vector<int32_t>* /*configs*/) {
+    int64_t display_id, std::vector<int32_t>* configs) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t num_configs = 0;
+  hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayConfigs(&num_configs, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<hwc2_config_t> out_configs(num_configs);
+  error = Hwc2toHwc3Error(
+      display->GetDisplayConfigs(&num_configs, out_configs.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  configs->reserve(num_configs);
+  for (const auto config : out_configs) {
+    configs->emplace_back(Hwc2ConfigIdToHwc3(config));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(
-    int64_t /*display*/, DisplayConnectionType* /*type*/) {
+    int64_t display_id, DisplayConnectionType* type) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t out_type = 0;
+  const hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayConnectionType(&out_type));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  *type = Hwc2DisplayConnectionTypeToHwc3(out_type);
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(
-    int64_t /*display*/, DisplayIdentification* /*id*/) {
+    int64_t display_id, DisplayIdentification* id) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint8_t port = 0;
+  uint32_t data_size = 0;
+  hwc3::Error error = Hwc2toHwc3Error(
+      display->GetDisplayIdentificationData(&port, &data_size, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  id->data.resize(data_size);
+  error = Hwc2toHwc3Error(
+      display->GetDisplayIdentificationData(&port, &data_size,
+                                            id->data.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  id->port = static_cast<int8_t>(port);
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t /*display*/,
-                                                  std::string* /*name*/) {
+ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display_id,
+                                                  std::string* name) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t size = 0;
+  auto error = Hwc2toHwc3Error(display->GetDisplayName(&size, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  name->resize(size);
+  error = Hwc2toHwc3Error(display->GetDisplayName(&size, name->data()));
+  return ToBinderStatus(error);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(
-    int64_t /*display*/, int32_t* /*vsyncPeriod*/) {
+    int64_t display_id, int32_t* vsync_period) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t hwc2_vsync_period = 0;
+  auto error = Hwc2toHwc3Error(
+      display->GetDisplayVsyncPeriod(&hwc2_vsync_period));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  *vsync_period = static_cast<int32_t>(hwc2_vsync_period);
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(
-    int64_t /*display*/, int64_t /*maxFrames*/, int64_t /*timestamp*/,
+    int64_t /*display_id*/, int64_t /*max_frames*/, int64_t /*timestamp*/,
     DisplayContentSample* /*samples*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
-    int64_t /*display*/, DisplayContentSamplingAttributes* /*attrs*/) {
+    int64_t /*display_id*/, DisplayContentSamplingAttributes* /*attrs*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
-    int64_t /*display*/, common::Transform* /*orientation*/) {
+    int64_t display_id, common::Transform* orientation) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  *orientation = common::Transform::NONE;
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getHdrCapabilities(
-    int64_t /*display*/, HdrCapabilities* /*caps*/) {
+ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display_id,
+                                                      HdrCapabilities* caps) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  /* No HDR capabilities */
+  caps->types.clear();
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(
-    int32_t* /*count*/) {
+ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  *count = static_cast<int32_t>(hwc_->GetMaxVirtualDisplayCount());
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(
-    int64_t /*display*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
+    int64_t /*display_id*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(
-    int64_t /*display*/, ReadbackBufferAttributes* /*attrs*/) {
+    int64_t /*display_id*/, ReadbackBufferAttributes* /*attrs*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(
-    int64_t /*display*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
+    int64_t /*display_id*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getRenderIntents(
-    int64_t /*display*/, ColorMode /*mode*/,
-    std::vector<RenderIntent>* /*intents*/) {
+    int64_t display_id, ColorMode mode, std::vector<RenderIntent>* intents) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  const int32_t hwc2_color_mode = Hwc3ColorModeToHwc2(mode);
+  uint32_t out_num_intents = 0;
+  auto error = Hwc2toHwc3Error(
+      display->GetRenderIntents(hwc2_color_mode, &out_num_intents, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<int32_t> out_intents(out_num_intents);
+  error = Hwc2toHwc3Error(display->GetRenderIntents(hwc2_color_mode,
+                                                    &out_num_intents,
+                                                    out_intents.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  intents->reserve(out_num_intents);
+  for (const auto intent : out_intents) {
+    intents->emplace_back(Hwc2RenderIntentToHwc3(intent));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(
-    int64_t /*display*/, std::vector<ContentType>* /*types*/) {
+    int64_t display_id, std::vector<ContentType>* types) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  uint32_t out_num_supported_types = 0;
+  auto error = Hwc2toHwc3Error(
+      display->GetSupportedContentTypes(&out_num_supported_types, nullptr));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  std::vector<uint32_t> out_supported_types(out_num_supported_types);
+  error = Hwc2toHwc3Error(
+      display->GetSupportedContentTypes(&out_num_supported_types,
+                                        out_supported_types.data()));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  for (const auto type : out_supported_types) {
+    types->push_back(Hwc2ContentTypeToHwc3(type));
+  }
   return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
-    int64_t /*display*/,
-    std::optional<common::DisplayDecorationSupport>* /*supportStruct*/) {
+    int64_t /*display_id*/,
+    std::optional<common::DisplayDecorationSupport>* /*support_struct*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::registerCallback(
-    const std::shared_ptr<IComposerCallback>& /*callback*/) {
+    const std::shared_ptr<IComposerCallback>& callback) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  // This function is specified to be called exactly once.
+  hwc_->Init(callback);
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t /*display*/,
-                                                   int32_t /*config*/) {
+ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display_id,
+                                                   int32_t config) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  return ToBinderStatus(Hwc2toHwc3Error(display->SetActiveConfig(config)));
 }
 
 ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
-    int64_t /*display*/, int32_t /*config*/,
-    const VsyncPeriodChangeConstraints& /*constraints*/,
-    VsyncPeriodChangeTimeline* /*timeline*/) {
+    int64_t display_id, int32_t config,
+    const VsyncPeriodChangeConstraints& constraints,
+    VsyncPeriodChangeTimeline* timeline) {
   DEBUG_FUNC();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  hwc_vsync_period_change_constraints_t hwc2_constraints;
+  hwc2_constraints.desiredTimeNanos = constraints.desiredTimeNanos;
+  hwc2_constraints.seamlessRequired = static_cast<uint8_t>(
+      constraints.seamlessRequired);
+
+  hwc_vsync_period_change_timeline_t hwc2_timeline{};
+  auto error = Hwc2toHwc3Error(
+      display->SetActiveConfigWithConstraints(config, &hwc2_constraints,
+                                              &hwc2_timeline));
+  if (error != hwc3::Error::kNone) {
+    return ToBinderStatus(error);
+  }
+
+  timeline->refreshTimeNanos = hwc2_timeline.refreshTimeNanos;
+  timeline->newVsyncAppliedTimeNanos = hwc2_timeline.newVsyncAppliedTimeNanos;
+  timeline->refreshRequired = static_cast<bool>(hwc2_timeline.refreshRequired);
   return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display*/,
+ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display_id*/,
                                                         int32_t /*config*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t /*display*/) {
+ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(
+    int64_t /*display_id*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
 ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(
-    int64_t /*display*/, int32_t* /*config*/) {
+    int64_t /*display_id*/, int32_t* /*config*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t /*display*/,
-                                                         bool /*on*/) {
+ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display_id,
+                                                         bool on) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = Hwc2toHwc3Error(display->SetAutoLowLatencyMode(on));
+  return ToBinderStatus(error);
 }
 
-ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t /*display*/,
-                                                            int32_t /*count*/) {
+ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display_id,
+                                                            int32_t count) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(
+      composer_resources_->SetDisplayClientTargetCacheSize(display_id, count));
 }
 
-ndk::ScopedAStatus ComposerClient::setColorMode(int64_t /*display*/,
-                                                ColorMode /*mode*/,
-                                                RenderIntent /*intent*/) {
+ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display_id,
+                                                ColorMode mode,
+                                                RenderIntent intent) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetColorModeWithIntent(Hwc3ColorModeToHwc2(mode),
+                                               Hwc3RenderIntentToHwc2(intent));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
-ndk::ScopedAStatus ComposerClient::setContentType(int64_t /*display*/,
-                                                  ContentType /*type*/) {
+ndk::ScopedAStatus ComposerClient::setContentType(int64_t display_id,
+                                                  ContentType type) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetContentType(Hwc3ContentTypeToHwc2(type));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
 ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
-    int64_t /*display*/, bool /*enable*/,
+    int64_t /*display_id*/, bool /*enable*/,
     FormatColorComponent /*componentMask*/, int64_t /*maxFrames*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t /*display*/,
-                                                PowerMode /*mode*/) {
+ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display_id,
+                                                PowerMode mode) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetPowerMode(Hwc3PowerModeToHwc2(mode));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
 ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
-    int64_t /*display*/, const AidlNativeHandle& /*aidlBuffer*/,
+    int64_t /*display_id*/, const AidlNativeHandle& /*aidlBuffer*/,
     const ndk::ScopedFileDescriptor& /*releaseFence*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
 }
 
-ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t /*display*/,
-                                                   bool /*enabled*/) {
+ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display_id,
+                                                   bool enabled) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
+  HwcDisplay* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    return ToBinderStatus(hwc3::Error::kBadDisplay);
+  }
+
+  auto error = display->SetVsyncEnabled(static_cast<int32_t>(enabled));
+  return ToBinderStatus(Hwc2toHwc3Error(error));
 }
 
-ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display*/,
+ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display_id*/,
                                                        int32_t /*timeout*/) {
   DEBUG_FUNC();
-  return ndk::ScopedAStatus::ok();
+  return ToBinderStatus(hwc3::Error::kUnsupported);
+}
+
+std::string ComposerClient::Dump() {
+  uint32_t size = 0;
+  hwc_->Dump(&size, nullptr);
+
+  std::string buffer(size, '\0');
+  hwc_->Dump(&size, &buffer.front());
+  return buffer;
 }
 
 ::ndk::SpAIBinder ComposerClient::createBinder() {
@@ -299,4 +926,335 @@
   return binder;
 }
 
+void ComposerClient::ExecuteSetLayerBuffer(int64_t display_id,
+                                           HwcLayerWrapper& layer,
+                                           const Buffer& buffer) {
+  buffer_handle_t imported_buffer = nullptr;
+
+  auto releaser = composer_resources_->CreateResourceReleaser(true);
+  auto err = composer_resources_->GetLayerBuffer(display_id, layer.layer_id,
+                                                 buffer, &imported_buffer,
+                                                 releaser.get());
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+    return;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+  auto fence_fd = const_cast<ndk::ScopedFileDescriptor&>(buffer.fence)
+                      .release();
+  err = Hwc2toHwc3Error(layer.layer->SetLayerBuffer(imported_buffer, fence_fd));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerBlendMode(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableBlendMode& blend_mode) {
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerBlendMode(
+      Hwc3BlendModeToHwc2(blend_mode.blendMode)));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerComposition(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableComposition& composition) {
+  hwc3::Error error = hwc3::Error::kNone;
+  switch (composition.composition) {
+      // Unsupported composition types should set an error for the current
+      // DisplayCommand.
+    case Composition::DISPLAY_DECORATION:
+    case Composition::SIDEBAND:
+      error = hwc3::Error::kUnsupported;
+      break;
+    default:
+      error = Hwc2toHwc3Error(layer.layer->SetLayerCompositionType(
+          Hwc3CompositionToHwc2(composition.composition)));
+  }
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerDataspace(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableDataspace& dataspace) {
+  auto err = Hwc2toHwc3Error(
+      layer.layer->SetLayerDataspace(Hwc3DataspaceToHwc2(dataspace.dataspace)));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerDisplayFrame(int64_t /*display_id*/,
+                                                 HwcLayerWrapper& layer,
+                                                 const common::Rect& rect) {
+  const hwc_rect_t hwc2_rect{rect.left, rect.top, rect.right, rect.bottom};
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerDisplayFrame(hwc2_rect));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+void ComposerClient::ExecuteSetLayerPlaneAlpha(int64_t /*display_id*/,
+                                               HwcLayerWrapper& layer,
+                                               const PlaneAlpha& plane_alpha) {
+  auto err = Hwc2toHwc3Error(
+      layer.layer->SetLayerPlaneAlpha(plane_alpha.alpha));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerSourceCrop(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const common::FRect& source_crop) {
+  const hwc_frect_t rect{source_crop.left, source_crop.top, source_crop.right,
+                         source_crop.bottom};
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerSourceCrop(rect));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+void ComposerClient::ExecuteSetLayerTransform(
+    int64_t /*display_id*/, HwcLayerWrapper& layer,
+    const ParcelableTransform& transform) {
+  auto err = Hwc2toHwc3Error(
+      layer.layer->SetLayerTransform(Hwc3TransformToHwc2(transform.transform)));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+void ComposerClient::ExecuteSetLayerZOrder(int64_t /*display_id*/,
+                                           HwcLayerWrapper& layer,
+                                           const ZOrder& z_order) {
+  auto err = Hwc2toHwc3Error(layer.layer->SetLayerZOrder(z_order.z));
+  if (err != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(err);
+  }
+}
+
+void ComposerClient::ExecuteSetLayerBrightness(
+    int64_t /*display_id*/, HwcLayerWrapper& /*layer*/,
+    const LayerBrightness& brightness) {
+  if (std::signbit(brightness.brightness) ||
+      std::isnan(brightness.brightness)) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadParameter);
+  }
+}
+
+void ComposerClient::ExecuteSetDisplayBrightness(
+    uint64_t display_id, const DisplayBrightness& command) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto error = Hwc2toHwc3Error(
+      display->SetDisplayBrightness(command.brightness));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+void ComposerClient::ExecuteSetDisplayColorTransform(
+    uint64_t display_id, const std::vector<float>& matrix) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto almost_equal = [](auto a, auto b) {
+    const float epsilon = 0.001F;
+    return std::abs(a - b) < epsilon;
+  };
+  const bool is_identity = std::equal(matrix.begin(), matrix.end(),
+                                      kIdentityMatrix.begin(), almost_equal);
+
+  const int32_t hint = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
+                                   : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
+
+  auto error = Hwc2toHwc3Error(display->SetColorTransform(matrix.data(), hint));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+void ComposerClient::ExecuteSetDisplayClientTarget(
+    uint64_t display_id, const ClientTarget& command) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  hwc_region_t damage_regions;
+  damage_regions.numRects = command.damage.size();
+
+  std::vector<hwc_rect_t> regions(command.damage.size());
+  for (const auto& region : command.damage) {
+    regions.push_back({region.left, region.top, region.right, region.bottom});
+  }
+  damage_regions.rects = regions.data();
+
+  buffer_handle_t imported_buffer = nullptr;
+  auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
+
+  auto error = composer_resources_->GetDisplayClientTarget(display_id,
+                                                           command.buffer,
+                                                           &imported_buffer,
+                                                           buf_releaser.get());
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+  auto fence = const_cast<::ndk::ScopedFileDescriptor&>(command.buffer.fence)
+                   .release();
+  error = Hwc2toHwc3Error(
+      display->SetClientTarget(imported_buffer, fence,
+                               Hwc3DataspaceToHwc2(command.dataspace),
+                               damage_regions));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+}
+
+void ComposerClient::ExecuteSetDisplayOutputBuffer(uint64_t display_id,
+                                                   const Buffer& buffer) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  buffer_handle_t imported_buffer = nullptr;
+  auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
+
+  auto error = composer_resources_->GetDisplayOutputBuffer(display_id, buffer,
+                                                           &imported_buffer,
+                                                           buf_releaser.get());
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
+  auto fence = const_cast<::ndk::ScopedFileDescriptor&>(buffer.fence).release();
+  error = Hwc2toHwc3Error(display->SetOutputBuffer(imported_buffer, fence));
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+}
+void ComposerClient::ExecuteValidateDisplay(
+    int64_t display_id,
+    std::optional<ClockMonotonicTimestamp> /*expected_present_time*/
+) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  /* TODO: Handle expectedPresentTime */
+
+  std::vector<int64_t> changed_layers;
+  std::vector<Composition> composition_types;
+  int32_t display_request_mask = 0;
+  std::vector<int64_t> requested_layers;
+  std::vector<int32_t> request_masks;
+
+  const hwc3::Error error = ValidateDisplayInternal(*display, &changed_layers,
+                                                    &composition_types,
+                                                    &display_request_mask,
+                                                    &requested_layers,
+                                                    &request_masks, nullptr,
+                                                    nullptr);
+
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+
+  // If a CommandError has been been set for the current DisplayCommand, then
+  // no other results should be returned besides the error.
+  if (cmd_result_writer_->HasError()) {
+    return;
+  }
+
+  DisplayChanges changes{};
+  for (size_t i = 0; i < composition_types.size(); i++) {
+    changes.AddLayerCompositionChange(display_id, changed_layers[i],
+                                      composition_types[i]);
+  }
+
+  std::vector<DisplayRequest::LayerRequest> layer_requests;
+  for (size_t i = 0; i < requested_layers.size(); i++) {
+    layer_requests.push_back({requested_layers[i], request_masks[i]});
+  }
+
+  const DisplayRequest request_changes{display_id, display_request_mask,
+                                       layer_requests};
+  changes.display_request_changes = request_changes;
+
+  cmd_result_writer_->AddChanges(changes);
+  composer_resources_->SetDisplayMustValidateState(display_id, false);
+}
+
+void ComposerClient::ExecuteAcceptDisplayChanges(int64_t display_id) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  auto error = Hwc2toHwc3Error(display->AcceptDisplayChanges());
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+    return;
+  }
+}
+
+void ComposerClient::ExecutePresentDisplay(int64_t display_id) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  ::android::base::unique_fd display_fence;
+  std::unordered_map<int64_t, ::android::base::unique_fd> release_fences;
+  auto error = PresentDisplayInternal(display_id, display_fence,
+                                      release_fences);
+  if (error != hwc3::Error::kNone) {
+    cmd_result_writer_->AddError(error);
+  }
+  if (cmd_result_writer_->HasError()) {
+    return;
+  }
+
+  cmd_result_writer_->AddPresentFence(display_id, std::move(display_fence));
+  cmd_result_writer_->AddReleaseFence(display_id, release_fences);
+}
+
+void ComposerClient::ExecutePresentOrValidateDisplay(
+    int64_t display_id,
+    std::optional<ClockMonotonicTimestamp> expected_present_time) {
+  auto* display = GetDisplay(display_id);
+  if (display == nullptr) {
+    cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
+    return;
+  }
+
+  /* TODO: Handle expectedPresentTime */
+  /* TODO: Add check if it's possible to skip display validation */
+  ExecuteValidateDisplay(display_id, expected_present_time);
+  cmd_result_writer_
+      ->AddPresentOrValidateResult(display_id,
+                                   PresentOrValidate::Result::Validated);
+}
+
 }  // namespace aidl::android::hardware::graphics::composer3::impl
