Add Parcelable AidlComposer commands

Change the command interface to use parcelables instead of FMQ.

Bug: 201008710
Test: VTS
Change-Id: Iac67330eb34a5bcf253580e8109a67bd90483d85
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
index cfafc50..3722803 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
@@ -31,8 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.common;
+@VintfStability
+parcelable Point {
+  int x;
+  int y;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/common/aidl/android/hardware/graphics/common/Point.aidl
index 10de558..b3ede44 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
@@ -14,18 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.common;
 
 /**
- * Layer requests returned from getDisplayRequests.
+ * General purpose definition of a point.
  */
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable Point {
+    int x;
+    int y;
 }
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index e33c653..9034138 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,12 +31,14 @@
         enabled: true,
         support_system_process: true,
     },
-    srcs: ["android/hardware/graphics/composer3/*.aidl"],
+    srcs: [
+        "android/hardware/graphics/composer3/*.aidl",
+        "android/hardware/graphics/composer3/command/*.aidl",
+    ],
     stability: "vintf",
     imports: [
         "android.hardware.graphics.common-V3",
         "android.hardware.common-V2",
-        "android.hardware.common.fmq-V1",
     ],
     backend: {
         cpp: {
@@ -73,6 +75,7 @@
     vendor_available: true,
     shared_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
+        "android.hardware.common-V2-ndk",
         "libbase",
         "libfmq",
         "libsync",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
deleted file mode 100644
index a522d53..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index e19105d..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum Command {
-  LENGTH_MASK = 65535,
-  OPCODE_SHIFT = 16,
-  OPCODE_MASK = -65536,
-  SELECT_DISPLAY = 0,
-  SELECT_LAYER = 65536,
-  SET_ERROR = 16777216,
-  SET_CHANGED_COMPOSITION_TYPES = 16842752,
-  SET_DISPLAY_REQUESTS = 16908288,
-  SET_PRESENT_FENCE = 16973824,
-  SET_RELEASE_FENCES = 17039360,
-  SET_COLOR_TRANSFORM = 33554432,
-  SET_CLIENT_TARGET = 33619968,
-  SET_OUTPUT_BUFFER = 33685504,
-  VALIDATE_DISPLAY = 33751040,
-  ACCEPT_DISPLAY_CHANGES = 33816576,
-  PRESENT_DISPLAY = 33882112,
-  PRESENT_OR_VALIDATE_DISPLAY = 33947648,
-  SET_LAYER_CURSOR_POSITION = 50331648,
-  SET_LAYER_BUFFER = 50397184,
-  SET_LAYER_SURFACE_DAMAGE = 50462720,
-  SET_LAYER_BLEND_MODE = 67108864,
-  SET_LAYER_COLOR = 67174400,
-  SET_LAYER_COMPOSITION_TYPE = 67239936,
-  SET_LAYER_DATASPACE = 67305472,
-  SET_LAYER_DISPLAY_FRAME = 67371008,
-  SET_LAYER_PLANE_ALPHA = 67436544,
-  SET_LAYER_SIDEBAND_STREAM = 67502080,
-  SET_LAYER_SOURCE_CROP = 67567616,
-  SET_LAYER_TRANSFORM = 67633152,
-  SET_LAYER_VISIBLE_REGION = 67698688,
-  SET_LAYER_Z_ORDER = 67764224,
-  SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 67829760,
-  SET_LAYER_PER_FRAME_METADATA = 50528256,
-  SET_LAYER_FLOAT_COLOR = 67895296,
-  SET_LAYER_COLOR_TRANSFORM = 67960832,
-  SET_LAYER_PER_FRAME_METADATA_BLOBS = 50593792,
-  SET_CLIENT_TARGET_PROPERTY = 17104896,
-  SET_LAYER_GENERIC_METADATA = 68026368,
-  SET_LAYER_WHITE_POINT_NITS = 50659328,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index d7cab2b..65cf86c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -38,7 +38,7 @@
   android.hardware.graphics.composer3.VirtualDisplay createVirtualDisplay(int width, int height, android.hardware.graphics.common.PixelFormat formatHint, int outputBufferSlotCount);
   void destroyLayer(long display, long layer);
   void destroyVirtualDisplay(long display);
-  android.hardware.graphics.composer3.ExecuteCommandsStatus executeCommands(int inLength, in android.hardware.common.NativeHandle[] inHandles);
+  android.hardware.graphics.composer3.command.CommandResultPayload[] executeCommands(in android.hardware.graphics.composer3.command.CommandPayload[] commands);
   int getActiveConfig(long display);
   android.hardware.graphics.composer3.ColorMode[] getColorModes(long display);
   float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace);
@@ -56,7 +56,6 @@
   android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
   android.hardware.graphics.composer3.LayerGenericMetadataKey[] getLayerGenericMetadataKeys();
   int getMaxVirtualDisplayCount();
-  android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> getOutputCommandQueue();
   android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
   android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
   ParcelFileDescriptor getReadbackBufferFence(long display);
@@ -71,7 +70,6 @@
   void setContentType(long display, android.hardware.graphics.composer3.ContentType type);
   void setDisplayBrightness(long display, float brightness);
   void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames);
-  void setInputCommandQueue(in android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> descriptor);
   void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
   void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in ParcelFileDescriptor releaseFence);
   void setVsyncEnabled(long display, boolean enabled);
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
similarity index 89%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
index 26e7d97..cead848 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Buffer.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable Buffer {
+  int slot;
+  @nullable android.hardware.common.NativeHandle handle;
+  @nullable ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
index 26e7d97..1377c6c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ChangedCompositionTypes {
+  long display;
+  android.hardware.graphics.composer3.command.ChangedCompositionTypes.Layer[] layers;
+  @VintfStability
+  parcelable Layer {
+    long layer;
+    android.hardware.graphics.composer3.Composition composition;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
index 26e7d97..c3f4700 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTarget.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ClientTarget {
+  android.hardware.graphics.composer3.command.Buffer buffer;
+  android.hardware.graphics.common.Dataspace dataspace;
+  android.hardware.graphics.common.Rect[] damage;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
index 41a1afe..b690a57 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
@@ -31,10 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ClientTargetPropertyWithNits {
+  long display;
+  android.hardware.graphics.composer3.ClientTargetProperty clientTargetProperty;
+  float whitePointNits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
index 41a1afe..0b3071c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
@@ -31,10 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ColorTransformPayload {
+  float[] matrix;
+  android.hardware.graphics.common.ColorTransform hint;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
index 26e7d97..9848306 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandPayload.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+union CommandPayload {
+  android.hardware.graphics.composer3.command.DisplayCommand displayCommand;
+  android.hardware.graphics.composer3.command.LayerCommand layerCommand;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
index 41a1afe..1b3cae8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
@@ -31,10 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+union CommandResultPayload {
+  android.hardware.graphics.composer3.command.Error error;
+  android.hardware.graphics.composer3.command.ChangedCompositionTypes changedCompositionType;
+  android.hardware.graphics.composer3.command.DisplayRequest displayRequest;
+  android.hardware.graphics.composer3.command.PresentFence presentFence;
+  android.hardware.graphics.composer3.command.ReleaseFences releaseFences;
+  android.hardware.graphics.composer3.command.PresentOrValidate presentOrValidateResult;
+  android.hardware.graphics.composer3.command.ClientTargetPropertyWithNits clientTargetProperty;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
similarity index 77%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
index 41a1afe..7446db0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayCommand.aidl
@@ -31,10 +31,15 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable DisplayCommand {
+  long display;
+  @nullable android.hardware.graphics.composer3.command.ColorTransformPayload colorTransform;
+  @nullable android.hardware.graphics.composer3.command.ClientTarget clientTarget;
+  @nullable android.hardware.graphics.composer3.command.Buffer virtualDisplayOutputBuffer;
+  boolean validateDisplay;
+  boolean acceptDisplayChanges;
+  boolean presentDisplay;
+  boolean presentOrValidateDisplay;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
similarity index 80%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
index 26e7d97..7f413a9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/DisplayRequest.aidl
@@ -31,9 +31,18 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable DisplayRequest {
+  long display;
+  int mask;
+  android.hardware.graphics.composer3.command.DisplayRequest.LayerRequest[] layerRequests;
+  const int FLIP_CLIENT_TARGET = 1;
+  const int WRITE_CLIENT_TARGET_TO_OUTPUT = 2;
+  @VintfStability
+  parcelable LayerRequest {
+    long layer;
+    int mask;
+    const int CLEAR_CLIENT_TARGET = 1;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
index cfafc50..1726ea5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/Error.aidl
@@ -31,8 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable Error {
+  int commandIndex;
+  int errorCode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
similarity index 90%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
index 41a1afe..be889d8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/GenericMetadata.aidl
@@ -31,10 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable GenericMetadata {
+  android.hardware.graphics.composer3.LayerGenericMetadataKey key;
+  byte[] value;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl
new file mode 100644
index 0000000..b5adbc3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/LayerCommand.aidl
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable LayerCommand {
+  long display;
+  long layer;
+  @nullable android.hardware.graphics.common.Point cursorPosition;
+  @nullable android.hardware.graphics.composer3.command.Buffer buffer;
+  @nullable android.hardware.graphics.common.Rect[] damage;
+  @nullable android.hardware.graphics.composer3.command.ParcelableBlendMode blendMode;
+  @nullable android.hardware.graphics.composer3.Color color;
+  @nullable android.hardware.graphics.composer3.FloatColor floatColor;
+  @nullable android.hardware.graphics.composer3.command.ParcelableComposition composition;
+  @nullable android.hardware.graphics.composer3.command.ParcelableDataspace dataspace;
+  @nullable android.hardware.graphics.common.Rect displayFrame;
+  @nullable android.hardware.graphics.composer3.command.PlaneAlpha planeAlpha;
+  @nullable android.hardware.common.NativeHandle sidebandStream;
+  @nullable android.hardware.graphics.common.FRect sourceCrop;
+  @nullable android.hardware.graphics.composer3.command.ParcelableTransform transform;
+  @nullable android.hardware.graphics.common.Rect[] visibleRegion;
+  @nullable android.hardware.graphics.composer3.command.ZOrder z;
+  @nullable float[] colorTransform;
+  @nullable android.hardware.graphics.composer3.command.WhitePointNits whitePointNits;
+  @nullable android.hardware.graphics.composer3.command.GenericMetadata genericMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
similarity index 90%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
index 26e7d97..5e6d212 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableBlendMode {
+  android.hardware.graphics.common.BlendMode blendMode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
index 26e7d97..40637a9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableComposition {
+  android.hardware.graphics.composer3.Composition composition;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
index 26e7d97..8f06079 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableDataspace {
+  android.hardware.graphics.common.Dataspace dataspace;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
index 26e7d97..6d6fe5b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ParcelableTransform {
+  android.hardware.graphics.common.Transform transform;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
index cfafc50..97f5329 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
@@ -31,8 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable PlaneAlpha {
+  float alpha;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
similarity index 91%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
index cfafc50..906f20c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentFence.aidl
@@ -31,8 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable PresentFence {
+  long display;
+  ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
index 41a1afe..66f1c03 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
@@ -31,10 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable PresentOrValidate {
+  long display;
+  android.hardware.graphics.composer3.command.PresentOrValidate.Result result;
+  @VintfStability
+  enum Result {
+    Presented = 0,
+    Validated = 1,
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
index 41a1afe..b7d2586 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ReleaseFences.aidl
@@ -31,10 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ReleaseFences {
+  long display;
+  android.hardware.graphics.composer3.command.ReleaseFences.Layer[] layers;
+  @VintfStability
+  parcelable Layer {
+    long layer;
+    ParcelFileDescriptor fence;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
similarity index 92%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
index cfafc50..2b25167 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/WhitePointNits.aidl
@@ -31,8 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable WhitePointNits {
+  float nits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
index cfafc50..69b68c4 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/command/ZOrder.aidl
@@ -31,8 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.composer3.command;
+@VintfStability
+parcelable ZOrder {
+  int z;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index 95c07ac..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,763 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.composer3;
-
-import android.hardware.graphics.composer3.Command;
-
-/**
- * The command interface allows composer3 to reduce binder overhead by sending
- * atomic command stream in a command message queue. These commands are usually
- * sent on a per frame basic and contains the information that describes how the
- * display is composited. @see IComposerClient.executeCommands.
- */
-@VintfStability
-@Backing(type="int")
-enum Command {
-    LENGTH_MASK = 0xffff,
-    OPCODE_SHIFT = 16,
-    OPCODE_MASK = 0xffff << OPCODE_SHIFT,
-
-    // special commands
-
-    /**
-     * SELECT_DISPLAY has this pseudo prototype
-     *
-     *   selectDisplay(long display);
-     *
-     * Selects the current display implied by all other commands.
-     *
-     * @param display is the newly selected display.
-     */
-    SELECT_DISPLAY = 0x000 << OPCODE_SHIFT,
-
-    /**
-     * SELECT_LAYER has this pseudo prototype
-     *
-     *   selectLayer(long layer);
-     *
-     * Selects the current layer implied by all implicit layer commands.
-     *
-     * @param layer is the newly selected layer.
-     */
-    SELECT_LAYER = 0x001 << OPCODE_SHIFT,
-
-    // value commands (for return values)
-
-    /**
-     * SET_ERROR has this pseudo prototype
-     *
-     *   setError(uint32_t location, int error);
-     *
-     * Indicates an error generated by a command.
-     *
-     * @param location is the offset of the command in the input command
-     *        message queue.
-     * @param error is the error generated by the command.
-     */
-    SET_ERROR = 0x100 << OPCODE_SHIFT,
-
-    /**
-     * SET_CHANGED_COMPOSITION_TYPES has this pseudo prototype
-     *
-     *   setChangedCompositionTypes(long[] layers,
-     *                              Composition[] types);
-     *
-     * Sets the layers for which the device requires a different composition
-     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
-     * client must either update its state with these types and call
-     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
-     * the display again.
-     *
-     * @param layers is an array of layer handles.
-     * @param types is an array of composition types, each corresponding to
-     *         an element of layers.
-     */
-    SET_CHANGED_COMPOSITION_TYPES = 0x101 << OPCODE_SHIFT,
-
-    /**
-     * SET_DISPLAY_REQUESTS has this pseudo prototype
-     *
-     *   setDisplayRequests(int displayRequestMask,
-     *                      long[] layers,
-     *                      int[] layerRequestMasks);
-     *
-     * Sets the display requests and the layer requests required for the last
-     * validated configuration.
-     *
-     * Display requests provide information about how the client must handle
-     * the client target. Layer requests provide information about how the
-     * client must handle an individual layer.
-     *
-     * @param displayRequestMask is the display requests for the current
-     *        validated state.
-     * @param layers is an array of layers which all have at least one
-     *        request.
-     * @param layerRequestMasks is the requests corresponding to each element
-     *        of layers.
-     */
-    SET_DISPLAY_REQUESTS = 0x102 << OPCODE_SHIFT,
-
-    /**
-     * SET_PRESENT_FENCE has this pseudo prototype
-     *
-     *   setPresentFence(int presentFenceIndex);
-     *
-     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
-     * displays, this fence must be signaled at the vsync when the result
-     * of composition of this frame starts to appear (for video-mode panels)
-     * or starts to transfer to panel memory (for command-mode panels). For
-     * virtual displays, this fence must be signaled when writes to the output
-     * buffer have completed and it is safe to read from it.
-     *
-     * @param presentFenceIndex is an index into outHandles array.
-     */
-    SET_PRESENT_FENCE = 0x103 << OPCODE_SHIFT,
-
-    /**
-     * SET_RELEASE_FENCES has this pseudo prototype
-     *
-     *   setReleaseFences(long[] layers,
-     *                    int[] releaseFenceIndices);
-     *
-     * Sets the release fences for device layers on this display which will
-     * receive new buffer contents this frame.
-     *
-     * A release fence is a file descriptor referring to a sync fence object
-     * which must be signaled after the device has finished reading from the
-     * buffer presented in the prior frame. This indicates that it is safe to
-     * start writing to the buffer again. If a given layer's fence is not
-     * returned from this function, it must be assumed that the buffer
-     * presented on the previous frame is ready to be written.
-     *
-     * The fences returned by this function must be unique for each layer
-     * (even if they point to the same underlying sync object).
-     *
-     * @param layers is an array of layer handles.
-     * @param releaseFenceIndices are indices into outHandles array, each
-     *        corresponding to an element of layers.
-     */
-    SET_RELEASE_FENCES = 0x104 << OPCODE_SHIFT,
-
-    // display commands
-
-    /**
-     * SET_COLOR_TRANSFORM has this pseudo prototype
-     *
-     *   setColorTransform(float[16] matrix,
-     *                     ColorTransform hint);
-     *
-     * Sets a color transform which will be applied after composition.
-     *
-     * If hint is not ColorTransform::ARBITRARY, then the device may use the
-     * hint to apply the desired color transform instead of using the color
-     * matrix directly.
-     *
-     * If the device is not capable of either using the hint or the matrix to
-     * apply the desired color transform, it must force all layers to client
-     * composition during VALIDATE_DISPLAY.
-     *
-     * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
-     * the client must never apply the color transform during client
-     * composition, even if all layers are being composed by the client.
-     *
-     * The matrix provided is an affine color transformation of the following
-     * form:
-     *
-     * |r.r r.g r.b 0|
-     * |g.r g.g g.b 0|
-     * |b.r b.g b.b 0|
-     * |Tr  Tg  Tb  1|
-     *
-     * This matrix must be provided in row-major form:
-     *
-     * {r.r, r.g, r.b, 0, g.r, ...}.
-     *
-     * Given a matrix of this form and an input color [R_in, G_in, B_in], the
-     * output color [R_out, G_out, B_out] will be:
-     *
-     * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
-     * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
-     * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
-     *
-     * @param matrix is a 4x4 transform matrix (16 floats) as described above.
-     * @param hint is a hint value which may be used instead of the given
-     *        matrix unless it is ColorTransform::ARBITRARY.
-     */
-    SET_COLOR_TRANSFORM = 0x200 << OPCODE_SHIFT,
-
-    /**
-     * SET_CLIENT_TARGET has this pseudo prototype
-     *
-     *   setClientTarget(int targetSlot,
-     *                   int targetIndex,
-     *                   int acquireFenceIndex,
-     *                   android.hardware.graphics.common.Dataspace dataspace,
-     *                   Rect[] damage);
-     *
-     * Sets the buffer handle which will receive the output of client
-     * composition.  Layers marked as Composition::CLIENT must be composited
-     * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
-     * marked as Composition::CLIENT must be composited with this buffer by
-     * the device.
-     *
-     * The buffer handle provided may be empty if no layers are being
-     * composited by the client. This must not result in an error (unless an
-     * invalid display handle is also provided).
-     *
-     * Also provides a file descriptor referring to an acquire sync fence
-     * object, which must be signaled when it is safe to read from the client
-     * target buffer.  If it is already safe to read from this buffer, an
-     * empty handle may be passed instead.
-     *
-     * For more about dataspaces, see SET_LAYER_DATASPACE.
-     *
-     * The damage parameter describes a surface damage region as defined in
-     * the description of SET_LAYER_SURFACE_DAMAGE.
-     *
-     * Will be called before PRESENT_DISPLAY if any of the layers are marked
-     * as Composition::CLIENT. If no layers are so marked, then it is not
-     * necessary to call this function. It is not necessary to call
-     * validateDisplay after changing the target through this function.
-     *
-     * @param targetSlot is the client target buffer slot to use.
-     * @param targetIndex is an index into inHandles for the new target
-     *        buffer.
-     * @param acquireFenceIndex is an index into inHandles for a sync fence
-     *        file descriptor as described above.
-     * @param dataspace is the dataspace of the buffer, as described in
-     *        setLayerDataspace.
-     * @param damage is the surface damage region.
-     *
-     */
-    SET_CLIENT_TARGET = 0x201 << OPCODE_SHIFT,
-
-    /**
-     * SET_OUTPUT_BUFFER has this pseudo prototype
-     *
-     *   setOutputBuffer(int bufferSlot,
-     *                   int bufferIndex,
-     *                   int releaseFenceIndex);
-     *
-     * Sets the output buffer for a virtual display. That is, the buffer to
-     * which the composition result will be written.
-     *
-     * Also provides a file descriptor referring to a release sync fence
-     * object, which must be signaled when it is safe to write to the output
-     * buffer. If it is already safe to write to the output buffer, an empty
-     * handle may be passed instead.
-     *
-     * Must be called at least once before PRESENT_DISPLAY, but does not have
-     * any interaction with layer state or display validation.
-     *
-     * @param bufferSlot is the new output buffer.
-     * @param bufferIndex is the new output buffer.
-     * @param releaseFenceIndex is a sync fence file descriptor as described
-     *        above.
-     */
-    SET_OUTPUT_BUFFER = 0x202 << OPCODE_SHIFT,
-
-    /**
-     * VALIDATE_DISPLAY has this pseudo prototype
-     *
-     *   validateDisplay();
-     *
-     * Instructs the device to inspect all of the layer state and determine if
-     * there are any composition type changes necessary before presenting the
-     * display. Permitted changes are described in the definition of
-     * Composition above.
-     */
-    VALIDATE_DISPLAY = 0x203 << OPCODE_SHIFT,
-
-    /**
-     * ACCEPT_DISPLAY_CHANGES has this pseudo prototype
-     *
-     *   acceptDisplayChanges();
-     *
-     * Accepts the changes required by the device from the previous
-     * validateDisplay call (which may be queried using
-     * getChangedCompositionTypes) and revalidates the display. This function
-     * is equivalent to requesting the changed types from
-     * getChangedCompositionTypes, setting those types on the corresponding
-     * layers, and then calling validateDisplay again.
-     *
-     * After this call it must be valid to present this display. Calling this
-     * after validateDisplay returns 0 changes must succeed with NONE, but
-     * must have no other effect.
-     */
-    ACCEPT_DISPLAY_CHANGES = 0x204 << OPCODE_SHIFT,
-
-    /**
-     * PRESENT_DISPLAY has this pseudo prototype
-     *
-     *   presentDisplay();
-     *
-     * Presents the current display contents on the screen (or in the case of
-     * virtual displays, into the output buffer).
-     *
-     * Prior to calling this function, the display must be successfully
-     * validated with validateDisplay. Note that setLayerBuffer and
-     * setLayerSurfaceDamage specifically do not count as layer state, so if
-     * there are no other changes to the layer state (or to the buffer's
-     * properties as described in setLayerBuffer), then it is safe to call
-     * this function without first validating the display.
-     */
-    PRESENT_DISPLAY = 0x205 << OPCODE_SHIFT,
-
-    /**
-     * PRESENT_OR_VALIDATE_DISPLAY has this pseudo prototype
-     *
-     *   presentOrValidateDisplay();
-     *
-     * Presents the current display contents on the screen (or in the case of
-     * virtual displays, into the output buffer) if validate can be skipped,
-     * or perform a VALIDATE_DISPLAY action instead.
-     */
-    PRESENT_OR_VALIDATE_DISPLAY = 0x206 << OPCODE_SHIFT,
-
-    // layer commands (VALIDATE_DISPLAY not required)
-
-    /**
-     * SET_LAYER_CURSOR_POSITION has this pseudo prototype
-     *
-     *   setLayerCursorPosition(int x, int y);
-     *
-     * Asynchronously sets the position of a cursor layer.
-     *
-     * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
-     * If validation succeeds (i.e., the device does not request a composition
-     * change for that layer), then once a buffer has been set for the layer
-     * and it has been presented, its position may be set by this function at
-     * any time between presentDisplay and any subsequent validateDisplay
-     * calls for this display.
-     *
-     * Once validateDisplay is called, this function must not be called again
-     * until the validate/present sequence is completed.
-     *
-     * May be called from any thread so long as it is not interleaved with the
-     * validate/present sequence as described above.
-     *
-     * @param layer is the layer to which the position is set.
-     * @param x is the new x coordinate (in pixels from the left of the
-     *        screen).
-     * @param y is the new y coordinate (in pixels from the top of the
-     *        screen).
-     */
-    SET_LAYER_CURSOR_POSITION = 0x300 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_BUFFER has this pseudo prototype
-     *
-     *   setLayerBuffer(int bufferSlot,
-     *                  int bufferIndex,
-     *                  int acquireFenceIndex);
-     *
-     * Sets the buffer handle to be displayed for this layer. If the buffer
-     * properties set at allocation time (width, height, format, and usage)
-     * have not changed since the previous frame, it is not necessary to call
-     * validateDisplay before calling presentDisplay unless new state needs to
-     * be validated in the interim.
-     *
-     * Also provides a file descriptor referring to an acquire sync fence
-     * object, which must be signaled when it is safe to read from the given
-     * buffer. If it is already safe to read from the buffer, an empty handle
-     * may be passed instead.
-     *
-     * This function must return NONE and have no other effect if called for a
-     * layer with a composition type of Composition::SOLID_COLOR (because it
-     * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
-     * synchronization and buffer updates for these layers are handled
-     * elsewhere).
-     *
-     * @param layer is the layer to which the buffer is set.
-     * @param bufferSlot is the buffer slot to use.
-     * @param bufferIndex is the buffer handle to set.
-     * @param acquireFenceIndex is a sync fence file descriptor as described above.
-     */
-    SET_LAYER_BUFFER = 0x301 << OPCODE_SHIFT,
-
-    /*
-     * SET_LAYER_SURFACE_DAMAGE has this pseudo prototype
-     *
-     *   setLayerSurfaceDamage(Rect[] damage);
-     *
-     * Provides the region of the source buffer which has been modified since
-     * the last frame. This region does not need to be validated before
-     * calling presentDisplay.
-     *
-     * Once set through this function, the damage region remains the same
-     * until a subsequent call to this function.
-     *
-     * If damage is non-empty, then it may be assumed that any portion of the
-     * source buffer not covered by one of the rects has not been modified
-     * this frame. If damage is empty, then the whole source buffer must be
-     * treated as if it has been modified.
-     *
-     * If the layer's contents are not modified relative to the prior frame,
-     * damage must contain exactly one empty rect([0, 0, 0, 0]).
-     *
-     * The damage rects are relative to the pre-transformed buffer, and their
-     * origin is the top-left corner. They must not exceed the dimensions of
-     * the latched buffer.
-     *
-     * @param layer is the layer to which the damage region is set.
-     * @param damage is the new surface damage region.
-     */
-    SET_LAYER_SURFACE_DAMAGE = 0x302 << OPCODE_SHIFT,
-
-    // layer state commands (VALIDATE_DISPLAY required)
-
-    /**
-     * SET_LAYER_BLEND_MODE has this pseudo prototype
-     *
-     *   setLayerBlendMode(android.hardware.graphics.common.BlendMode mode)
-     *
-     * Sets the blend mode of the given layer.
-     *
-     * @param mode is the new blend mode.
-     */
-    SET_LAYER_BLEND_MODE = 0x400 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COLOR has this pseudo prototype
-     *
-     *   setLayerColor(Color color);
-     *
-     * Sets the color of the given layer. If the composition type of the layer
-     * is not Composition::SOLID_COLOR, this call must succeed and have no
-     * other effect.
-     *
-     * @param color is the new color.
-     */
-    SET_LAYER_COLOR = 0x401 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COMPOSITION_TYPE has this pseudo prototype
-     *
-     *   setLayerCompositionType(Composition type);
-     *
-     * Sets the desired composition type of the given layer. During
-     * validateDisplay, the device may request changes to the composition
-     * types of any of the layers as described in the definition of
-     * Composition above.
-     *
-     * @param type is the new composition type.
-     */
-    SET_LAYER_COMPOSITION_TYPE = 0x402 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_DATASPACE has this pseudo prototype
-     *
-     *   setLayerDataspace(android.hardware.graphics.common.Dataspace dataspace);
-     *
-     * Sets the dataspace of the layer.
-     *
-     * The dataspace provides more information about how to interpret the buffer
-     * or solid color, such as the encoding standard and color transform.
-     *
-     * See the values of Dataspace for more information.
-     *
-     * @param dataspace is the new dataspace.
-     */
-    SET_LAYER_DATASPACE = 0x403 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_DISPLAY_FRAME has this pseudo prototype
-     *
-     *   setLayerDisplayFrame(Rect frame);
-     *
-     * Sets the display frame (the portion of the display covered by a layer)
-     * of the given layer. This frame must not exceed the display dimensions.
-     *
-     * @param frame is the new display frame.
-     */
-    SET_LAYER_DISPLAY_FRAME = 0x404 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_PLANE_ALPHA has this pseudo prototype
-     *
-     *   setLayerPlaneAlpha(float alpha);
-     *
-     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
-     * which will be applied to the whole layer. It can be conceptualized as a
-     * preprocessing step which applies the following function:
-     *   if (blendMode == BlendMode::PREMULTIPLIED)
-     *       out.rgb = in.rgb * planeAlpha
-     *   out.a = in.a * planeAlpha
-     *
-     * If the device does not support this operation on a layer which is
-     * marked Composition::DEVICE, it must request a composition type change
-     * to Composition::CLIENT upon the next validateDisplay call.
-     *
-     * @param alpha is the plane alpha value to apply.
-     */
-    SET_LAYER_PLANE_ALPHA = 0x405 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_SIDEBAND_STREAM has this pseudo prototype
-     *
-     *   setLayerSidebandStream(int streamIndex)
-     *
-     * Sets the sideband stream for this layer. If the composition type of the
-     * given layer is not Composition::SIDEBAND, this call must succeed and
-     * have no other effect.
-     *
-     * @param streamIndex is the new sideband stream.
-     */
-    SET_LAYER_SIDEBAND_STREAM = 0x406 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_SOURCE_CROP has this pseudo prototype
-     *
-     *   setLayerSourceCrop(FRect crop);
-     *
-     * Sets the source crop (the portion of the source buffer which will fill
-     * the display frame) of the given layer. This crop rectangle must not
-     * exceed the dimensions of the latched buffer.
-     *
-     * If the device is not capable of supporting a true float source crop
-     * (i.e., it will truncate or round the floats to integers), it must set
-     * this layer to Composition::CLIENT when crop is non-integral for the
-     * most accurate rendering.
-     *
-     * If the device cannot support float source crops, but still wants to
-     * handle the layer, it must use the following code (or similar) to
-     * convert to an integer crop:
-     *   intCrop.left = (int) ceilf(crop.left);
-     *   intCrop.top = (int) ceilf(crop.top);
-     *   intCrop.right = (int) floorf(crop.right);
-     *   intCrop.bottom = (int) floorf(crop.bottom);
-     *
-     * @param crop is the new source crop.
-     */
-    SET_LAYER_SOURCE_CROP = 0x407 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_TRANSFORM has this pseudo prototype
-     *
-     * Sets the transform (rotation/flip) of the given layer.
-     *
-     *   setLayerTransform(Transform transform);
-     *
-     * @param transform is the new transform.
-     */
-    SET_LAYER_TRANSFORM = 0x408 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_VISIBLE_REGION has this pseudo prototype
-     *
-     *   setLayerVisibleRegion(Rect[] visible);
-     *
-     * Specifies the portion of the layer that is visible, including portions
-     * under translucent areas of other layers. The region is in screen space,
-     * and must not exceed the dimensions of the screen.
-     *
-     * @param visible is the new visible region, in screen space.
-     */
-    SET_LAYER_VISIBLE_REGION = 0x409 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_Z_ORDER has this pseudo prototype
-     *
-     *   setLayerZOrder(int z);
-     *
-     * Sets the desired Z order (height) of the given layer. A layer with a
-     * greater Z value occludes a layer with a lesser Z value.
-     *
-     * @param z is the new Z order.
-     */
-    SET_LAYER_Z_ORDER = 0x40a << OPCODE_SHIFT,
-
-    /**
-     * SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT has this pseudo prototype
-     *
-     * setPresentOrValidateDisplayResult(int state);
-     *
-     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
-     * @param state is the state of present or validate
-     *    1 - Present Succeeded
-     *    0 - Validate succeeded
-     */
-    SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 0x40b << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_PER_FRAME_METADATA has this pseudo prototype
-     *
-     *   setLayerPerFrameMetadata(long display, long layer,
-     *                            PerFrameMetadata[] data);
-     *
-     * Sets the PerFrameMetadata for the display. This metadata must be used
-     * by the implementation to better tone map content to that display.
-     *
-     * This is a method that may be called every frame. Thus it's
-     * implemented using buffered transport.
-     * SET_LAYER_PER_FRAME_METADATA is the command used by the buffered transport
-     * mechanism.
-     */
-    SET_LAYER_PER_FRAME_METADATA = 0x303 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_FLOAT_COLOR has this pseudo prototype
-     *
-     *   setLayerColor(FloatColor color);
-     *
-     * Sets the color of the given layer. If the composition type of the layer
-     * is not Composition::SOLID_COLOR, this call must succeed and have no
-     * other effect.
-     *
-     * @param color is the new color using float type.
-     */
-    SET_LAYER_FLOAT_COLOR = 0x40c << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
-     *
-     *   setLayerColorTransform(float[16] matrix);
-     *
-     * This command has the following binary layout in bytes:
-     *
-     *     0 - 16 * 4: matrix
-     *
-     * Sets a matrix for color transform which will be applied on this layer
-     * before composition.
-     *
-     * If the device is not capable of apply the matrix on this layer, it must force
-     * this layer to client composition during VALIDATE_DISPLAY.
-     *
-     * The matrix provided is an affine color transformation of the following
-     * form:
-     *
-     * |r.r r.g r.b 0|
-     * |g.r g.g g.b 0|
-     * |b.r b.g b.b 0|
-     * |Tr  Tg  Tb  1|
-     *
-     * This matrix must be provided in row-major form:
-     *
-     * {r.r, r.g, r.b, 0, g.r, ...}.
-     *
-     * Given a matrix of this form and an input color [R_in, G_in, B_in],
-     * the input color must first be converted to linear space
-     * [R_linear, G_linear, B_linear], then the output linear color
-     * [R_out_linear, G_out_linear, B_out_linear] will be:
-     *
-     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
-     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
-     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
-     *
-     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
-     * gamma space: [R_out, G_out, B_out] before blending.
-     *
-     * @param matrix is a 4x4 transform matrix (16 floats) as described above.
-     */
-
-    SET_LAYER_COLOR_TRANSFORM = 0x40d << OPCODE_SHIFT,
-    /*
-     * SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
-     *
-     *   setLayerPerFrameMetadataBlobs(long display, long layer,
-     *                                   PerFrameMetadataBlob[] metadata);
-     *
-     *   This command sends metadata that may be used for tone-mapping the
-     *   associated layer.  The metadata structure follows a {key, blob}
-     *   format (see the PerFrameMetadataBlob struct).  All keys must be
-     *   returned by a prior call to getPerFrameMetadataKeys and must
-     *   be part of the list of keys associated with blob-type metadata
-     *   (see PerFrameMetadataKey).
-     *
-     *   This method may be called every frame.
-     */
-    SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << OPCODE_SHIFT,
-
-    /**
-     * SET_CLIENT_TARGET_PROPERTY has this pseudo prototype
-     *
-     * This command has the following binary layout in bytes:
-     *
-     *     0 - 3: clientTargetProperty.pixelFormat
-     *     4 - 7: clientTargetProperty.dataspace
-     *     8 - 11: whitePointNits
-     *
-     * The white point parameter describes the intended white point of the client target buffer.
-     * When client composition blends both HDR and SDR content, the client must composite to the
-     * brightness space as specified by the hardware composer. This is so that adjusting the real
-     * display brightness may be applied atomically with compensating the client target output. For
-     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
-     * the SDR buffers when an HDR layer is simultaneously device-composited.
-     *
-     *   setClientTargetProperty(ClientTargetProperty clientTargetProperty, float whitePointNits);
-     */
-    SET_CLIENT_TARGET_PROPERTY = 0x105 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_GENERIC_METADATA has this pseudo prototype
-     *
-     *   setLayerGenericMetadata(string key, bool mandatory, byte[] value);
-     *
-     * Sets a piece of generic metadata for the given layer. If this
-     * function is called twice with the same key but different values, the
-     * newer value must override the older one. Calling this function with a
-     * 0-length value must reset that key's metadata as if it had not been
-     * set.
-     *
-     * A given piece of metadata may either be mandatory or a hint
-     * (non-mandatory) as indicated by the second parameter. Mandatory
-     * metadata may affect the composition result, which is to say that it
-     * may cause a visible change in the final image. By contrast, hints may
-     * only affect the composition strategy, such as which layers are
-     * composited by the client, but must not cause a visible change in the
-     * final image. The value of the mandatory flag shall match the value
-     * returned from getLayerGenericMetadataKeys for the given key.
-     *
-     * Only keys which have been returned from getLayerGenericMetadataKeys()
-     * shall be accepted. Any other keys must result in an UNSUPPORTED error.
-     *
-     * The value passed into this function shall be the binary
-     * representation of a HIDL type corresponding to the given key. For
-     * example, a key of 'com.example.V1_3.Foo' shall be paired with a
-     * value of type com.example@1.3::Foo, which would be defined in a
-     * vendor HAL extension.
-     *
-     * This function will be encoded in the command buffer in this order:
-     *   1) The key length, stored as a uint32_t
-     *   2) The key itself, padded to a uint32_t boundary if necessary
-     *   3) The mandatory flag, stored as a uint32_t
-     *   4) The value length in bytes, stored as a uint32_t
-     *   5) The value itself, padded to a uint32_t boundary if necessary
-     *
-     * @param key indicates which metadata value should be set on this layer
-     * @param mandatory indicates whether this particular key represents
-     *        mandatory metadata or a hint (non-mandatory metadata), as
-     *        described above
-     * @param value is a binary representation of a HIDL struct
-     *        corresponding to the key as described above
-     */
-    SET_LAYER_GENERIC_METADATA = 0x40e << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_WHITE_POINT_NITS has this pseudo prototype
-     *
-     *   setLayerWhitePointNits(float sdrWhitePointNits);
-     *
-     * Sets the desired white point for the layer. This is intended to be used when presenting
-     * an SDR layer alongside HDR content. The HDR content will be presented at the display
-     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
-     * provided.
-     *
-     * @param whitePointNits is the white point in nits.
-     */
-    SET_LAYER_WHITE_POINT_NITS = 0x305 << OPCODE_SHIFT,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
deleted file mode 100644
index 4b3d31a..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.composer3;
-
-/**
- * Display requests returned by getDisplayRequests.
- */
-@VintfStability
-@Backing(type="int")
-enum DisplayRequest {
-    /**
-     * Instructs the client to provide a new client target buffer, even if
-     * no layers are marked for client composition.
-     */
-    FLIP_CLIENT_TARGET = 1 << 0,
-    /**
-     * Instructs the client to write the result of client composition
-     * directly into the virtual display output buffer. If any of the
-     * layers are not marked as Composition::CLIENT or the given display
-     * is not a virtual display, this request has no effect.
-     */
-    WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 230980d..f661f8b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -16,11 +16,8 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.common.fmq.MQDescriptor;
-import android.hardware.common.fmq.SynchronizedReadWrite;
 import android.hardware.graphics.composer3.ClientTargetProperty;
 import android.hardware.graphics.composer3.ColorMode;
-import android.hardware.graphics.composer3.Command;
 import android.hardware.graphics.composer3.ContentType;
 import android.hardware.graphics.composer3.DisplayAttribute;
 import android.hardware.graphics.composer3.DisplayCapability;
@@ -28,7 +25,6 @@
 import android.hardware.graphics.composer3.DisplayContentSample;
 import android.hardware.graphics.composer3.DisplayContentSamplingAttributes;
 import android.hardware.graphics.composer3.DisplayIdentification;
-import android.hardware.graphics.composer3.ExecuteCommandsStatus;
 import android.hardware.graphics.composer3.FormatColorComponent;
 import android.hardware.graphics.composer3.HdrCapabilities;
 import android.hardware.graphics.composer3.IComposerCallback;
@@ -40,6 +36,8 @@
 import android.hardware.graphics.composer3.VirtualDisplay;
 import android.hardware.graphics.composer3.VsyncPeriodChangeConstraints;
 import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
+import android.hardware.graphics.composer3.command.CommandPayload;
+import android.hardware.graphics.composer3.command.CommandResultPayload;
 
 @VintfStability
 interface IComposerClient {
@@ -159,23 +157,13 @@
     void destroyVirtualDisplay(long display);
 
     /**
-     * Executes commands from the input command message queue. Return values
-     * generated by the input commands are written to the output command
-     * message queue in the form of value commands.
+     * Executes commands.
      *
-     * @param inLength is the length of input commands.
-     * @param inHandles is an array of handles referenced by the input
-     *        commands.
+     * @param commands are the commands to be processed.
      *
-     * @return is the status of the command.
-
-     * @exception EX_BAD_PARAMETER when inLength is not equal to the length of
-     *                       commands in the input command message queue.
-     * @exception NO_RESOURCES when the output command message queue was not
-     *                      properly drained.
+     * @return are the command statuses.
      */
-    ExecuteCommandsStatus executeCommands(
-            int inLength, in android.hardware.common.NativeHandle[] inHandles);
+    CommandResultPayload[] executeCommands(in CommandPayload[] commands);
 
     /**
      * Retrieves which display configuration is currently active.
@@ -436,17 +424,6 @@
     int getMaxVirtualDisplayCount();
 
     /**
-     * Gets the output command message queue.
-     *
-     * This function must only be called inside executeCommands closure.
-     *
-     * @return is the descriptor of the output command queue.
-     *
-     * @exception EX_NO_RESOURCES when failed to get the queue temporarily.
-     */
-    MQDescriptor<int, SynchronizedReadWrite> getOutputCommandQueue();
-
-    /**
      * Returns the PerFrameMetadataKeys that are supported by this device.
      *
      * @param display is the display on which to create the layer.
@@ -732,14 +709,6 @@
             long display, boolean enable, FormatColorComponent componentMask, long maxFrames);
 
     /**
-     * Sets the input command message queue.
-     *
-     * @param descriptor is the descriptor of the input command message queue.
-     * @exception EX_NO_RESOURCES when failed to set the queue temporarily.
-     */
-    void setInputCommandQueue(in MQDescriptor<int, SynchronizedReadWrite> descriptor);
-
-    /**
      * Sets the power mode of the given display. The transition must be
      * complete when this function returns. It is valid to call this function
      * multiple times with the same power mode.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
index b666e6a..3962920 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -16,8 +16,6 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.graphics.composer3.PerFrameMetadataKey;
-
 /**
  * PerFrameMetadataKey
  *
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl
new file mode 100644
index 0000000..3a08d3b
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Buffer.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.common.NativeHandle;
+
+@VintfStability
+parcelable Buffer {
+    /**
+     * Buffer slot in the range [0, bufferSlotCount) where bufferSlotCount is
+     * the parameter used when the layer was created.
+     * @see IComposer.createLayer.
+     * The slot is used as a buffer caching mechanism. When the Buffer.handle
+     * is null, the implementation uses the previous buffer associated with this
+     * slot.
+     */
+    int slot;
+
+    /**
+     * Buffer Handle. Can be null if this is the same buffer that was sent
+     * previously on this slot.
+     */
+    @nullable NativeHandle handle;
+
+    /**
+     * Buffer fence that represents when it is safe to access the buffer.
+     * A null fence indicates that the buffer can be accessed immediately.
+     */
+    @nullable ParcelFileDescriptor fence;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
new file mode 100644
index 0000000..3800eff
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ChangedCompositionTypes.aidl
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.Composition;
+
+@VintfStability
+parcelable ChangedCompositionTypes {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    @VintfStability
+    parcelable Layer {
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+
+        /**
+         * The new composition type.
+         */
+        Composition composition;
+    }
+
+    /**
+     * Indicates which layers has composition changes
+     */
+    Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
similarity index 60%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
index f67c3ce..d8d45a1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTarget.aidl
@@ -14,23 +14,26 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Output parameters for IComposerClient.executeCommands
- */
+import android.hardware.graphics.common.Dataspace;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.command.Buffer;
+
 @VintfStability
-parcelable ExecuteCommandsStatus {
+parcelable ClientTarget {
     /**
-     * Indicates whether the output command message queue has changed.
+     * Client target Buffer
      */
-    boolean queueChanged;
+    Buffer buffer;
+
     /**
-     * Indicates whether the output command message queue has changed.
+     * The dataspace of the buffer, as described in LayerCommand.dataspace.
      */
-    int length;
+    Dataspace dataspace;
+
     /**
-     * An array of handles referenced by the output commands.
+     * The surface damage regions.
      */
-    android.hardware.common.NativeHandle[] handles;
+    Rect[] damage;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
new file mode 100644
index 0000000..c80e4ce
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ClientTargetPropertyWithNits.aidl
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.ClientTargetProperty;
+
+@VintfStability
+parcelable ClientTargetPropertyWithNits {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The Client target property.
+     */
+    ClientTargetProperty clientTargetProperty;
+
+    /**
+     * The white points nits as described in CommandResultPayload.clientTargetProperty
+     */
+    float whitePointNits;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
similarity index 63%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
index c6fd063..9cc8fa7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ColorTransformPayload.aidl
@@ -14,25 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.common.ColorTransform;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable ColorTransformPayload {
     /**
-     * colorOut = colorSrc
+     * 4x4 transform matrix (16 floats) as described in DisplayCommand.colorTransform.
      */
-    NONE = 1,
+    float[] matrix;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * Hint value which may be used instead of the given matrix unless it
+     * is ColorTransform::ARBITRARY.
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    ColorTransform hint;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
index 10de558..c1555e6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandPayload.aidl
@@ -14,18 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.DisplayCommand;
+import android.hardware.graphics.composer3.command.LayerCommand;
 
 /**
- * Layer requests returned from getDisplayRequests.
+ * Type of commands that can be used in IComposerClient.executeCommands.
+ * Note that this is a union and each command can only have one type.
  */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+union CommandPayload {
+    DisplayCommand displayCommand;
+    LayerCommand layerCommand;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
new file mode 100644
index 0000000..b6086ca
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/CommandResultPayload.aidl
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.ChangedCompositionTypes;
+import android.hardware.graphics.composer3.command.ClientTargetPropertyWithNits;
+import android.hardware.graphics.composer3.command.DisplayRequest;
+import android.hardware.graphics.composer3.command.Error;
+import android.hardware.graphics.composer3.command.PresentFence;
+import android.hardware.graphics.composer3.command.PresentOrValidate;
+import android.hardware.graphics.composer3.command.ReleaseFences;
+
+@VintfStability
+union CommandResultPayload {
+    /**
+     * Indicates an error generated by a command.
+     */
+    Error error;
+
+    /**
+     * Sets the layers for which the device requires a different composition
+     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
+     * client must either update its state with these types and call
+     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
+     * the display again.
+     */
+    ChangedCompositionTypes changedCompositionType;
+
+    /**
+     * Sets the display requests and the layer requests required for the last
+     * validated configuration.
+     *
+     * Display requests provide information about how the client must handle
+     * the client target. Layer requests provide information about how the
+     * client must handle an individual layer.
+     */
+    DisplayRequest displayRequest;
+
+    /**
+     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
+     * displays, this fence must be signaled at the vsync when the result
+     * of composition of this frame starts to appear (for video-mode panels)
+     * or starts to transfer to panel memory (for command-mode panels). For
+     * virtual displays, this fence must be signaled when writes to the output
+     * buffer have completed and it is safe to read from it.
+     */
+    PresentFence presentFence;
+
+    /**
+     * Sets the release fences for device layers on this display which will
+     * receive new buffer contents this frame.
+     *
+     * A release fence is a file descriptor referring to a sync fence object
+     * which must be signaled after the device has finished reading from the
+     * buffer presented in the prior frame. This indicates that it is safe to
+     * start writing to the buffer again. If a given layer's fence is not
+     * returned from this function, it must be assumed that the buffer
+     * presented on the previous frame is ready to be written.
+     *
+     * The fences returned by this function must be unique for each layer
+     * (even if they point to the same underlying sync object).
+     *
+     */
+    ReleaseFences releaseFences;
+
+    /**
+     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
+     */
+    PresentOrValidate presentOrValidateResult;
+
+    /**
+     * The white point parameter describes the intended white point of the client target buffer.
+     * When client composition blends both HDR and SDR content, the client must composite to the
+     * brightness space as specified by the hardware composer. This is so that adjusting the real
+     * display brightness may be applied atomically with compensating the client target output. For
+     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
+     * the SDR buffers when an HDR layer is simultaneously device-composited.
+     */
+    ClientTargetPropertyWithNits clientTargetProperty;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl
new file mode 100644
index 0000000..7295ada
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayCommand.aidl
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.graphics.composer3.command.Buffer;
+import android.hardware.graphics.composer3.command.ClientTarget;
+import android.hardware.graphics.composer3.command.ColorTransformPayload;
+
+@VintfStability
+parcelable DisplayCommand {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * Sets a color transform which will be applied after composition.
+     *
+     * If hint is not ColorTransform::ARBITRARY, then the device may use the
+     * hint to apply the desired color transform instead of using the color
+     * matrix directly.
+     *
+     * If the device is not capable of either using the hint or the matrix to
+     * apply the desired color transform, it must force all layers to client
+     * composition during VALIDATE_DISPLAY.
+     *
+     * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
+     * the client must never apply the color transform during client
+     * composition, even if all layers are being composed by the client.
+     *
+     * The matrix provided is an affine color transformation of the following
+     * form:
+     *
+     * |r.r r.g r.b 0|
+     * |g.r g.g g.b 0|
+     * |b.r b.g b.b 0|
+     * |Tr  Tg  Tb  1|
+     *
+     * This matrix must be provided in row-major form:
+     *
+     * {r.r, r.g, r.b, 0, g.r, ...}.
+     *
+     * Given a matrix of this form and an input color [R_in, G_in, B_in], the
+     * output color [R_out, G_out, B_out] will be:
+     *
+     * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
+     * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
+     * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
+     *
+     */
+    @nullable ColorTransformPayload colorTransform;
+
+    /**
+     * Sets the buffer handle which will receive the output of client
+     * composition.  Layers marked as Composition::CLIENT must be composited
+     * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
+     * marked as Composition::CLIENT must be composited with this buffer by
+     * the device.
+     *
+     * The buffer handle provided may be empty if no layers are being
+     * composited by the client. This must not result in an error (unless an
+     * invalid display handle is also provided).
+     *
+     * Also provides a file descriptor referring to an acquire sync fence
+     * object, which must be signaled when it is safe to read from the client
+     * target buffer.  If it is already safe to read from this buffer, an
+     * empty handle may be passed instead.
+     *
+     * For more about dataspaces, see SET_LAYER_DATASPACE.
+     *
+     * The damage parameter describes a surface damage region as defined in
+     * the description of SET_LAYER_SURFACE_DAMAGE.
+     *
+     * Will be called before PRESENT_DISPLAY if any of the layers are marked
+     * as Composition::CLIENT. If no layers are so marked, then it is not
+     * necessary to call this function. It is not necessary to call
+     * validateDisplay after changing the target through this function.
+     */
+    @nullable ClientTarget clientTarget;
+
+    /**
+     * Sets the output buffer for a virtual display. That is, the buffer to
+     * which the composition result will be written.
+     *
+     * Also provides a file descriptor referring to a release sync fence
+     * object, which must be signaled when it is safe to write to the output
+     * buffer. If it is already safe to write to the output buffer, an empty
+     * handle may be passed instead.
+     *
+     * Must be called at least once before PRESENT_DISPLAY, but does not have
+     * any interaction with layer state or display validation.
+     */
+    @nullable Buffer virtualDisplayOutputBuffer;
+
+    /**
+     * Instructs the device to inspect all of the layer state and determine if
+     * there are any composition type changes necessary before presenting the
+     * display. Permitted changes are described in the definition of
+     * Composition above.
+     */
+    boolean validateDisplay;
+
+    /**
+     * Accepts the changes required by the device from the previous
+     * validateDisplay call (which may be queried using
+     * getChangedCompositionTypes) and revalidates the display. This function
+     * is equivalent to requesting the changed types from
+     * getChangedCompositionTypes, setting those types on the corresponding
+     * layers, and then calling validateDisplay again.
+     *
+     * After this call it must be valid to present this display. Calling this
+     * after validateDisplay returns 0 changes must succeed with NONE, but
+     * must have no other effect.
+     */
+    boolean acceptDisplayChanges;
+
+    /**
+     * Presents the current display contents on the screen (or in the case of
+     * virtual displays, into the output buffer).
+     *
+     * Prior to calling this function, the display must be successfully
+     * validated with validateDisplay. Note that setLayerBuffer and
+     * setLayerSurfaceDamage specifically do not count as layer state, so if
+     * there are no other changes to the layer state (or to the buffer's
+     * properties as described in setLayerBuffer), then it is safe to call
+     * this function without first validating the display.
+     */
+    boolean presentDisplay;
+
+    /**
+     * Presents the current display contents on the screen (or in the case of
+     * virtual displays, into the output buffer) if validate can be skipped,
+     * or perform a VALIDATE_DISPLAY action instead.
+     */
+    boolean presentOrValidateDisplay;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl
new file mode 100644
index 0000000..10bd10c
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/DisplayRequest.aidl
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+@VintfStability
+parcelable DisplayRequest {
+    /**
+     * Instructs the client to provide a new client target buffer, even if
+     * no layers are marked for client composition.
+     */
+    const int FLIP_CLIENT_TARGET = 1 << 0;
+
+    /**
+     * Instructs the client to write the result of client composition
+     * directly into the virtual display output buffer. If any of the
+     * layers are not marked as Composition::CLIENT or the given display
+     * is not a virtual display, this request has no effect.
+     */
+    const int WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1;
+
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The display requests for the current validated state. This must be a
+     * bitwise-or of the constants in `DisplayRequest`.
+     */
+    int mask;
+
+    @VintfStability
+    parcelable LayerRequest {
+        /**
+         * The client must clear its target with transparent pixels where
+         * this layer would be. The client may ignore this request if the
+         * layer must be blended.
+         */
+        const int CLEAR_CLIENT_TARGET = 1 << 0;
+
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+        /**
+         * The layer requests for the current validated state. This must be a
+         * bitwise-or of the constants in `LayerRequest`.
+         */
+        int mask;
+    }
+
+    /**
+     * The layer requests for the current validated state.
+     */
+    LayerRequest[] layerRequests;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
index 10de558..19843b9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/Error.aidl
@@ -14,18 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable Error {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The index in the command payload array.
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    int commandIndex;
+    /**
+     * The error generated by the command. Can be one of the IComposerClient.EX_*
+     */
+    int errorCode;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
index c6fd063..a4e1fe8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/GenericMetadata.aidl
@@ -14,25 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.composer3.LayerGenericMetadataKey;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable GenericMetadata {
     /**
-     * colorOut = colorSrc
+     * Indicates which metadata value should be set.
      */
-    NONE = 1,
+    LayerGenericMetadataKey key;
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The binary representation of a AIDL struct corresponding to
+     * the key as described above.
+     * TODO(b/209691612): revisit the use of byte[]
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    byte[] value;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl
new file mode 100644
index 0000000..eac051b
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/LayerCommand.aidl
@@ -0,0 +1,301 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.graphics.common.FRect;
+import android.hardware.graphics.common.Point;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.Color;
+import android.hardware.graphics.composer3.FloatColor;
+import android.hardware.graphics.composer3.PerFrameMetadata;
+import android.hardware.graphics.composer3.PerFrameMetadataBlob;
+import android.hardware.graphics.composer3.command.Buffer;
+import android.hardware.graphics.composer3.command.GenericMetadata;
+import android.hardware.graphics.composer3.command.ParcelableBlendMode;
+import android.hardware.graphics.composer3.command.ParcelableComposition;
+import android.hardware.graphics.composer3.command.ParcelableDataspace;
+import android.hardware.graphics.composer3.command.ParcelableTransform;
+import android.hardware.graphics.composer3.command.PlaneAlpha;
+import android.hardware.graphics.composer3.command.WhitePointNits;
+import android.hardware.graphics.composer3.command.ZOrder;
+
+@VintfStability
+parcelable LayerCommand {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The layer which this commands refers to.
+     * @see IComposer.createLayer
+     */
+    long layer;
+
+    /**
+     * Asynchronously sets the position of a cursor layer.
+     *
+     * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
+     * If validation succeeds (i.e., the device does not request a composition
+     * change for that layer), then once a buffer has been set for the layer
+     * and it has been presented, its position may be set by this function at
+     * any time between presentDisplay and any subsequent validateDisplay
+     * calls for this display.
+     *
+     * Once validateDisplay is called, this function must not be called again
+     * until the validate/present sequence is completed.
+     *
+     * May be called from any thread so long as it is not interleaved with the
+     * validate/present sequence as described above.
+     */
+    @nullable Point cursorPosition;
+
+    /**
+     * Sets the buffer handle to be displayed for this layer. If the buffer
+     * properties set at allocation time (width, height, format, and usage)
+     * have not changed since the previous frame, it is not necessary to call
+     * validateDisplay before calling presentDisplay unless new state needs to
+     * be validated in the interim.
+     *
+     * Also provides a file descriptor referring to an acquire sync fence
+     * object, which must be signaled when it is safe to read from the given
+     * buffer. If it is already safe to read from the buffer, an empty handle
+     * may be passed instead.
+     *
+     * This function must return NONE and have no other effect if called for a
+     * layer with a composition type of Composition::SOLID_COLOR (because it
+     * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
+     * synchronization and buffer updates for these layers are handled
+     * elsewhere).
+     */
+    @nullable Buffer buffer;
+
+    /**
+     * Provides the region of the source buffer which has been modified since
+     * the last frame. This region does not need to be validated before
+     * calling presentDisplay.
+     *
+     * Once set through this function, the damage region remains the same
+     * until a subsequent call to this function.
+     *
+     * If damage is non-empty, then it may be assumed that any portion of the
+     * source buffer not covered by one of the rects has not been modified
+     * this frame. If damage is empty, then the whole source buffer must be
+     * treated as if it has been modified.
+     *
+     * If the layer's contents are not modified relative to the prior frame,
+     * damage must contain exactly one empty rect([0, 0, 0, 0]).
+     *
+     * The damage rects are relative to the pre-transformed buffer, and their
+     * origin is the top-left corner. They must not exceed the dimensions of
+     * the latched buffer.
+     */
+    @nullable Rect[] damage;
+
+    /**
+     * Sets the blend mode of the given layer.
+     */
+    @nullable ParcelableBlendMode blendMode;
+
+    /**
+     * Sets the color of the given layer. If the composition type of the layer
+     * is not Composition::SOLID_COLOR, this call must succeed and have no
+     * other effect.
+     */
+    @nullable Color color;
+
+    /**
+     * Sets the color of the given layer. If the composition type of the layer
+     * is not Composition::SOLID_COLOR, this call must succeed and have no
+     * other effect.
+     */
+    @nullable FloatColor floatColor;
+
+    /**
+     * Sets the desired composition type of the given layer. During
+     * validateDisplay, the device may request changes to the composition
+     * types of any of the layers as described in the definition of
+     * Composition above.
+     */
+    @nullable ParcelableComposition composition;
+
+    /**
+     * Sets the dataspace of the layer.
+     *
+     * The dataspace provides more information about how to interpret the buffer
+     * or solid color, such as the encoding standard and color transform.
+     *
+     * See the values of ParcelableDataspace for more information.
+     */
+    @nullable ParcelableDataspace dataspace;
+
+    /**
+     * Sets the display frame (the portion of the display covered by a layer)
+     * of the given layer. This frame must not exceed the display dimensions.
+     */
+    @nullable Rect displayFrame;
+
+    /**
+     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
+     * which will be applied to the whole layer. It can be conceptualized as a
+     * preprocessing step which applies the following function:
+     *   if (blendMode == BlendMode::PREMULTIPLIED)
+     *       out.rgb = in.rgb * planeAlpha
+     *   out.a = in.a * planeAlpha
+     *
+     * If the device does not support this operation on a layer which is
+     * marked Composition::DEVICE, it must request a composition type change
+     * to Composition::CLIENT upon the next validateDisplay call.
+     *
+     */
+    @nullable PlaneAlpha planeAlpha;
+
+    /**
+     * Sets the sideband stream for this layer. If the composition type of the
+     * given layer is not Composition::SIDEBAND, this call must succeed and
+     * have no other effect.
+     */
+    @nullable NativeHandle sidebandStream;
+
+    /**
+     * Sets the source crop (the portion of the source buffer which will fill
+     * the display frame) of the given layer. This crop rectangle must not
+     * exceed the dimensions of the latched buffer.
+     *
+     * If the device is not capable of supporting a true float source crop
+     * (i.e., it will truncate or round the floats to integers), it must set
+     * this layer to Composition::CLIENT when crop is non-integral for the
+     * most accurate rendering.
+     *
+     * If the device cannot support float source crops, but still wants to
+     * handle the layer, it must use the following code (or similar) to
+     * convert to an integer crop:
+     *   intCrop.left = (int) ceilf(crop.left);
+     *   intCrop.top = (int) ceilf(crop.top);
+     *   intCrop.right = (int) floorf(crop.right);
+     *   intCrop.bottom = (int) floorf(crop.bottom);
+     */
+    @nullable FRect sourceCrop;
+
+    /**
+     * Sets the transform (rotation/flip) of the given layer.
+     */
+    @nullable ParcelableTransform transform;
+
+    /**
+     * Specifies the portion of the layer that is visible, including portions
+     * under translucent areas of other layers. The region is in screen space,
+     * and must not exceed the dimensions of the screen.
+     */
+    @nullable Rect[] visibleRegion;
+
+    /**
+     * Sets the desired Z order (height) of the given layer. A layer with a
+     * greater Z value occludes a layer with a lesser Z value.
+     */
+    @nullable ZOrder z;
+
+    /**
+     * Sets a matrix for color transform which will be applied on this layer
+     * before composition.
+     *
+     * If the device is not capable of apply the matrix on this layer, it must force
+     * this layer to client composition during VALIDATE_DISPLAY.
+     *
+     * The matrix provided is an affine color transformation of the following
+     * form:
+     *
+     * |r.r r.g r.b 0|
+     * |g.r g.g g.b 0|
+     * |b.r b.g b.b 0|
+     * |Tr  Tg  Tb  1|
+     *
+     * This matrix must be provided in row-major form:
+     *
+     * {r.r, r.g, r.b, 0, g.r, ...}.
+     *
+     * Given a matrix of this form and an input color [R_in, G_in, B_in],
+     * the input color must first be converted to linear space
+     * [R_linear, G_linear, B_linear], then the output linear color
+     * [R_out_linear, G_out_linear, B_out_linear] will be:
+     *
+     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
+     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
+     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
+     *
+     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
+     * gamma space: [R_out, G_out, B_out] before blending.
+     */
+    @nullable float[] colorTransform;
+
+    /**
+     * Sets the desired white point for the layer. This is intended to be used when presenting
+     * an SDR layer alongside HDR content. The HDR content will be presented at the display
+     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+     * provided.
+     */
+    @nullable WhitePointNits whitePointNits;
+
+    /**
+     * Sets a piece of generic metadata for the given layer. If this
+     * function is called twice with the same key but different values, the
+     * newer value must override the older one. Calling this function with a
+     * 0-length value must reset that key's metadata as if it had not been
+     * set.
+     *
+     * A given piece of metadata may either be mandatory or a hint
+     * (non-mandatory) as indicated by the second parameter. Mandatory
+     * metadata may affect the composition result, which is to say that it
+     * may cause a visible change in the final image. By contrast, hints may
+     * only affect the composition strategy, such as which layers are
+     * composited by the client, but must not cause a visible change in the
+     * final image. The value of the mandatory flag shall match the value
+     * returned from getLayerGenericMetadataKeys for the given key.
+     *
+     * Only keys which have been returned from getLayerGenericMetadataKeys()
+     * shall be accepted. Any other keys must result in an UNSUPPORTED error.
+     *
+     * The value passed into this function shall be the binary
+     * representation of a stable AIDL type corresponding to the given key. For
+     * example, a key of 'com.example.Foo-V2' shall be paired with a
+     * value of type com.exampleFoo-V2, which would be defined in a
+     * vendor HAL extension.
+     */
+    @nullable GenericMetadata genericMetadata;
+
+    /**
+     * Sets the PerFrameMetadata for the display. This metadata must be used
+     * by the implementation to better tone map content to that display.
+     *
+     * This is a command that may be called every frame.
+     */
+    @nullable PerFrameMetadata[] perFrameMetadata;
+
+    /**
+     * This command sends metadata that may be used for tone-mapping the
+     * associated layer.  The metadata structure follows a {key, blob}
+     * format (see the PerFrameMetadataBlob struct).  All keys must be
+     * returned by a prior call to getPerFrameMetadataKeys and must
+     * be part of the list of keys associated with blob-type metadata
+     * (see PerFrameMetadataKey).
+     *
+     * This command may be called every frame.
+     */
+    @nullable PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
index 10de558..f912853 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableBlendMode.aidl
@@ -14,18 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.BlendMode;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableBlendMode {
+    BlendMode blendMode;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
index 10de558..91979d8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableComposition.aidl
@@ -14,18 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.composer3.Composition;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableComposition {
+    Composition composition;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
index 10de558..6be750d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableDataspace.aidl
@@ -14,18 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.Dataspace;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableDataspace {
+    Dataspace dataspace;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
index 10de558..910d014 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ParcelableTransform.aidl
@@ -14,18 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.Transform;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableTransform {
+    Transform transform;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
index 10de558..fa1889b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PlaneAlpha.aidl
@@ -14,18 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PlaneAlpha {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * An alpha value (a floating point value in the range [0.0, 1.0])
+     * which will be applied to a whole layer.
+     * @see LayerCommand.planeAlpha
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    float alpha;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
index 10de558..0c14406 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentFence.aidl
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PresentFence {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    long display;
+
+    /**
+     * The present fence for this display.
+     */
+    ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
similarity index 64%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
index 10de558..7fc60c4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/PresentOrValidate.aidl
@@ -14,18 +14,19 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PresentOrValidate {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    long display;
+
+    /**
+     * Whether PresentOrValidate presented or validated the display.
+     */
+    @VintfStability enum Result { Presented, Validated }
+    Result result;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl
new file mode 100644
index 0000000..762f5eb
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ReleaseFences.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+@VintfStability
+parcelable ReleaseFences {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+    @VintfStability
+    parcelable Layer {
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+
+        /**
+         * The release fence for this layer.
+         */
+        ParcelFileDescriptor fence;
+    }
+
+    /**
+     * The layers which has release fences.
+     */
+    Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl
new file mode 100644
index 0000000..ec46cdf
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/WhitePointNits.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3.command;
+
+@VintfStability
+parcelable WhitePointNits {
+    /**
+     * The desired white point for the layer. This is intended to be used when presenting
+     * an SDR layer alongside HDR content. The HDR content will be presented at the display
+     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+     * provided.
+     * @see LayerCommand.whitePointNits.
+     */
+    float nits;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
index 10de558..68120b0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/command/ZOrder.aidl
@@ -14,18 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.composer3.command;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable ZOrder {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The desired Z order (height) of the given layer. A layer with a
+     * greater Z value occludes a layer with a lesser Z value.
+     * @see LayerCommand.z;
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    int z;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
index d59190d..5bda15a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
@@ -74,25 +74,25 @@
 static_assert(aidl::android::hardware::graphics::composer3::Capability::SKIP_VALIDATE ==
               static_cast<aidl::android::hardware::graphics::composer3::Capability>(4));
 
-static_assert(aidl::android::hardware::graphics::composer3::LayerRequest::CLEAR_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::LayerRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::LayerRequest::
-                              CLEAR_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::command::DisplayRequest::LayerRequest::
+                      CLEAR_CLIENT_TARGET ==
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       LayerRequest::CLEAR_CLIENT_TARGET));
 
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::INVALID ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::INVALID ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               INVALID));
 static_assert(
-        aidl::android::hardware::graphics::composer3::BlendMode::NONE ==
-        static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+        aidl::android::hardware::graphics::common::BlendMode::NONE ==
+        static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                 ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::NONE));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::PREMULTIPLIED ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::PREMULTIPLIED ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               PREMULTIPLIED));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::COVERAGE ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::COVERAGE ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               COVERAGE));
 
@@ -121,15 +121,14 @@
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::Composition::
                               SIDEBAND));
 
-static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::FLIP_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::
-                              DisplayRequest::FLIP_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::
+static_assert(
+        aidl::android::hardware::graphics::composer3::command::DisplayRequest::FLIP_CLIENT_TARGET ==
+        static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                 DisplayRequest::FLIP_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::command::DisplayRequest::
                       WRITE_CLIENT_TARGET_TO_OUTPUT ==
-              static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::
-                              DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
 
 static_assert(aidl::android::hardware::graphics::composer3::HandleIndex::EMPTY ==
               static_cast<aidl::android::hardware::graphics::composer3::HandleIndex>(
@@ -188,162 +187,6 @@
                 ::android::hardware::graphics::composer::V2_4::IComposerClient::DisplayCapability::
                         AUTO_LOW_LATENCY_MODE));
 
-static_assert(aidl::android::hardware::graphics::composer3::Command::LENGTH_MASK ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              LENGTH_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_SHIFT ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              OPCODE_SHIFT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_MASK ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              OPCODE_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SELECT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_LAYER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SELECT_LAYER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_ERROR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_ERROR));
-static_assert(
-        aidl::android::hardware::graphics::composer3::Command::SET_CHANGED_COMPOSITION_TYPES ==
-        static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                        SET_CHANGED_COMPOSITION_TYPES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_DISPLAY_REQUESTS ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_DISPLAY_REQUESTS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_PRESENT_FENCE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_PRESENT_FENCE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_RELEASE_FENCES ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_RELEASE_FENCES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_COLOR_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_COLOR_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_OUTPUT_BUFFER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_OUTPUT_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::VALIDATE_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::ACCEPT_DISPLAY_CHANGES ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              ACCEPT_DISPLAY_CHANGES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              PRESENT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_OR_VALIDATE_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              PRESENT_OR_VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_CURSOR_POSITION ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_CURSOR_POSITION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BUFFER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SURFACE_DAMAGE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SURFACE_DAMAGE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BLEND_MODE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_BLEND_MODE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COMPOSITION_TYPE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COMPOSITION_TYPE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DATASPACE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_DATASPACE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DISPLAY_FRAME ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_DISPLAY_FRAME));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PLANE_ALPHA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_PLANE_ALPHA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SIDEBAND_STREAM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SIDEBAND_STREAM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SOURCE_CROP ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SOURCE_CROP));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_VISIBLE_REGION ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_VISIBLE_REGION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_Z_ORDER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_Z_ORDER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::
-                      SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_PER_FRAME_METADATA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_FLOAT_COLOR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_FLOAT_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COLOR_TRANSFORM));
-static_assert(
-        aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS ==
-        static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                        SET_LAYER_PER_FRAME_METADATA_BLOBS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET_PROPERTY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_CLIENT_TARGET_PROPERTY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_GENERIC_METADATA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_GENERIC_METADATA));
-
 static_assert(aidl::android::hardware::graphics::composer3::DisplayAttribute::INVALID ==
               static_cast<aidl::android::hardware::graphics::composer3::DisplayAttribute>(
                       ::android::hardware::graphics::composer::V2_4::IComposerClient::Attribute::
@@ -612,4 +455,4 @@
     return true;
 }
 
-}  // namespace android::h2a
\ No newline at end of file
+}  // namespace android::h2a
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index 9bf8609..741572d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -35,7 +35,6 @@
         "VtsHalGraphicsComposer3_TargetTest.cpp",
         "VtsHalGraphicsComposer3_ReadbackTest.cpp",
         "composer-vts/GraphicsComposerCallback.cpp",
-        "composer-vts/TestCommandReader.cpp",
     ],
 
     shared_libs: [
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 4008cb4..717b60c 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -28,7 +28,6 @@
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
 #include "composer-vts/include/GraphicsComposerCallback.h"
-#include "composer-vts/include/TestCommandReader.h"
 
 namespace aidl::android::hardware::graphics::composer3::vts {
 namespace {
@@ -70,9 +69,7 @@
         EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
         mComposerCallback->setVsyncAllowed(false);
 
-        // set up command writer/reader and gralloc
-        mWriter = std::make_shared<CommandWriterBase>(1024);
-        mReader = std::make_unique<TestCommandReader>();
+        // set up gralloc
         mGraphicBuffer = allocate();
 
         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
@@ -104,8 +101,15 @@
 
     void TearDown() override {
         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
-        EXPECT_EQ(0, mReader->mErrors.size());
-        EXPECT_EQ(0, mReader->mCompositionChanges.size());
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+        ASSERT_TRUE(layers.empty());
+        ASSERT_TRUE(types.empty());
         if (mComposerCallback != nullptr) {
             EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
             EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
@@ -122,11 +126,6 @@
                 "VtsHalGraphicsComposer3_ReadbackTest");
     }
 
-    void clearCommandReaderState() {
-        mReader->mCompositionChanges.clear();
-        mReader->mErrors.clear();
-    }
-
     void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
         for (auto layer : layers) {
             layer->write(mWriter);
@@ -135,31 +134,18 @@
     }
 
     void execute() {
-        TestCommandReader* reader = mReader.get();
-        CommandWriterBase* writer = mWriter.get();
-        bool queueChanged = false;
-        int32_t commandLength = 0;
-        std::vector<NativeHandle> commandHandles;
-        ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
-        if (queueChanged) {
-            auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
-            ASSERT_TRUE(ret.isOk());
+        const auto& commands = mWriter.getPendingCommands();
+        if (commands.empty()) {
+            mWriter.reset();
+            return;
         }
 
-        ExecuteCommandsStatus commandStatus;
-        EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
-                            .isOk());
+        std::vector<command::CommandResultPayload> results;
+        const auto status = mComposerClient->executeCommands(commands, &results);
+        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
-        if (commandStatus.queueChanged) {
-            MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
-            ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
-            reader->setMQDescriptor(outputCommandQueue);
-        }
-        ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
-        reader->parse();
-        reader->reset();
-        writer->reset();
+        mReader.parse(results);
+        mWriter.reset();
     }
 
     bool getHasReadbackBuffer() {
@@ -181,8 +167,8 @@
     int32_t mDisplayWidth;
     int32_t mDisplayHeight;
     std::vector<ColorMode> mTestColorModes;
-    std::shared_ptr<CommandWriterBase> mWriter;
-    std::unique_ptr<TestCommandReader> mReader;
+    CommandWriterBase mWriter;
+    CommandReaderBase mReader;
     ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
     std::unique_ptr<TestRenderEngine> mTestRenderEngine;
 
@@ -246,7 +232,6 @@
 
 TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -272,20 +257,23 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
         // if hwc cannot handle and asks for composition change,
         // just succeed the test
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
@@ -296,7 +284,6 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -305,8 +292,6 @@
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
@@ -331,21 +316,24 @@
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
 
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
@@ -356,7 +344,6 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -380,7 +367,7 @@
         mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
                                    static_cast<uint32_t>(mDisplayHeight), 1,
                                    static_cast<uint32_t>(common::PixelFormat::RGBA_8888), usage);
-        mWriter->setLayerBuffer(0, mGraphicBuffer->handle, -1);
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer->getLayer(), 0, mGraphicBuffer->handle, -1);
 
         // expected color for each pixel
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -390,18 +377,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-        mWriter->validateDisplay();
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
@@ -470,7 +460,6 @@
                         .isOk());
 
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         EXPECT_TRUE(mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)
                             .isOk());
 
@@ -479,8 +468,6 @@
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
                                        {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
@@ -504,13 +491,18 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (!mReader->mCompositionChanges.empty()) {
-            ASSERT_EQ(1, mReader->mCompositionChanges.size());
-            ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            ASSERT_EQ(1, changedCompositionLayers.size());
+            ASSERT_EQ(1, changedCompositionTypes.size());
+            ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
 
             PixelFormat clientFormat = PixelFormat::RGBA_8888;
             auto clientUsage = static_cast<uint32_t>(
@@ -541,18 +533,20 @@
                     mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
 
             layer->setToClientComposition(mWriter);
-            mWriter->acceptDisplayChanges();
-            mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
-                                     std::vector<common::Rect>(1, damage));
+            mWriter.acceptDisplayChanges(mPrimaryDisplay);
+            mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+                                    clientDataspace, std::vector<common::Rect>(1, damage));
             execute();
-            ASSERT_EQ(0, mReader->mCompositionChanges.size());
+            mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                                &changedCompositionTypes);
+            ASSERT_TRUE(changedCompositionLayers.empty());
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
 
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
@@ -563,7 +557,6 @@
             mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
 
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -613,15 +606,18 @@
         clientLayer->setDisplayFrame(clientFrame);
         clientLayer->setZOrder(0);
         clientLayer->write(mWriter);
-        mWriter->validateDisplay();
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (mReader->mCompositionChanges.size() != 1) {
-            mReader->mCompositionChanges.clear();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (changedCompositionTypes.size() != 1) {
             continue;
         }
         // create client target buffer
-        ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+        ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
         mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
                                    static_cast<uint32_t>(mDisplayHeight),
                                    static_cast<int32_t>(common::PixelFormat::RGBA_8888),
@@ -642,23 +638,24 @@
         EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
 
         clientLayer->setToClientComposition(mWriter);
-        mWriter->acceptDisplayChanges();
-        mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
-                                 std::vector<common::Rect>(1, clientFrame));
+        mWriter.acceptDisplayChanges(mPrimaryDisplay);
+        mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+                                clientDataspace, std::vector<common::Rect>(1, clientFrame));
         execute();
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
-        ASSERT_EQ(0, mReader->mErrors.size());
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_EQ(0, changedCompositionLayers.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerDamage) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -667,8 +664,6 @@
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         common::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
 
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -689,18 +684,21 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 
@@ -716,14 +714,17 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_TRUE(changedCompositionLayers.empty());
+        ASSERT_TRUE(changedCompositionTypes.empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
@@ -731,7 +732,6 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -755,19 +755,22 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
@@ -780,7 +783,6 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -789,8 +791,6 @@
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
                                        {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
@@ -818,18 +818,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -839,7 +842,6 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -874,17 +876,20 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 
@@ -896,14 +901,17 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_TRUE(changedCompositionLayers.empty());
+        ASSERT_TRUE(changedCompositionTypes.empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
@@ -999,7 +1007,6 @@
 
 TEST_P(GraphicsBlendModeCompositionTest, None) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -1008,8 +1015,6 @@
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
         setBackgroundColor(BLACK);
@@ -1021,18 +1026,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
@@ -1043,7 +1051,6 @@
 
 TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -1052,8 +1059,6 @@
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
         setBackgroundColor(BLACK);
@@ -1066,25 +1071,27 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
 }
 
 TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -1092,7 +1099,6 @@
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
-        mWriter->selectDisplay(mPrimaryDisplay);
 
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
@@ -1105,18 +1111,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1128,7 +1137,7 @@
   protected:
     void SetUp() override {
         GraphicsCompositionTest::SetUp();
-        mWriter->selectDisplay(mPrimaryDisplay);
+
         auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
         backgroundLayer->setColor({0, 0, 0, 0});
         backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
@@ -1159,8 +1168,6 @@
 
 TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
     for (ColorMode mode : mTestColorModes) {
-        ASSERT_NE(nullptr, mWriter);
-        mWriter->selectDisplay(mPrimaryDisplay);
         auto error =
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC);
         if (!error.isOk() &&
@@ -1187,18 +1194,21 @@
                                        {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
 
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
@@ -1209,7 +1219,6 @@
 
 TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -1231,18 +1240,21 @@
                                        {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
 
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1252,7 +1264,6 @@
 
 TEST_P(GraphicsTransformCompositionTest, ROT_180) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
@@ -1275,18 +1286,20 @@
                                        {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
 
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (!mReader->mCompositionChanges.empty()) {
-            clearCommandReaderState();
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+        if (!layers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1313,4 +1326,4 @@
         ::android::PrintInstanceNameToString);
 
 }  // namespace
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index b9460c8..7a20a53 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -4,10 +4,10 @@
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include <aidl/android/hardware/graphics/common/FRect.h>
 #include <aidl/android/hardware/graphics/common/Rect.h>
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android-base/properties.h>
@@ -27,7 +27,6 @@
 #include <unordered_set>
 #include <utility>
 #include "composer-vts/include/GraphicsComposerCallback.h"
-#include "composer-vts/include/TestCommandReader.h"
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop  // ignored "-Wconversion
@@ -1148,45 +1147,33 @@
 // Tests for Command.
 class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
   protected:
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::SetUp());
-
-        mWriter = std::make_unique<CommandWriterBase>(1024);
-        mReader = std::make_unique<TestCommandReader>();
-    }
-
     void TearDown() override {
-        ASSERT_EQ(0, mReader->mErrors.size());
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+        ASSERT_TRUE(layers.empty());
+        ASSERT_TRUE(types.empty());
+
         ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
     }
 
     void execute() {
-        TestCommandReader* reader = mReader.get();
-        CommandWriterBase* writer = mWriter.get();
-        bool queueChanged = false;
-        int32_t commandLength = 0;
-        std::vector<NativeHandle> commandHandles;
-        ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
-        if (queueChanged) {
-            auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
-            ASSERT_TRUE(ret.isOk());
+        const auto& commands = mWriter.getPendingCommands();
+        if (commands.empty()) {
+            mWriter.reset();
+            return;
         }
 
-        ExecuteCommandsStatus commandStatus;
-        EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
-                            .isOk());
+        std::vector<command::CommandResultPayload> results;
+        const auto status = mComposerClient->executeCommands(commands, &results);
+        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
-        if (commandStatus.queueChanged) {
-            MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
-            ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
-            reader->setMQDescriptor(outputCommandQueue);
-        }
-        ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
-        reader->parse();
-        reader->reset();
-        writer->reset();
+        mReader.parse(results);
+        mWriter.reset();
     }
 
     static inline auto toTimePoint(nsecs_t time) {
@@ -1255,7 +1242,6 @@
             std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
         }
 
-        mWriter->selectDisplay(display.get());
         EXPECT_TRUE(mComposerClient->setPowerMode(display.get(), PowerMode::ON).isOk());
         EXPECT_TRUE(
                 mComposerClient
@@ -1270,42 +1256,41 @@
             ASSERT_EQ(::android::OK, buffer->initCheck());
             ASSERT_NE(nullptr, buffer->handle);
 
-            mWriter->selectLayer(layer);
-            mWriter->setLayerCompositionType(Composition::DEVICE);
-            mWriter->setLayerDisplayFrame(display.getFrameRect());
-            mWriter->setLayerPlaneAlpha(1);
-            mWriter->setLayerSourceCrop(display.getCrop());
-            mWriter->setLayerTransform(static_cast<Transform>(0));
-            mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
-            mWriter->setLayerZOrder(10);
-            mWriter->setLayerBlendMode(BlendMode::NONE);
-            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
-            mWriter->setLayerBuffer(0, buffer->handle, -1);
-            mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
+            mWriter.setLayerCompositionType(display.get(), layer, Composition::DEVICE);
+            mWriter.setLayerDisplayFrame(display.get(), layer, display.getFrameRect());
+            mWriter.setLayerPlaneAlpha(display.get(), layer, 1);
+            mWriter.setLayerSourceCrop(display.get(), layer, display.getCrop());
+            mWriter.setLayerTransform(display.get(), layer, static_cast<Transform>(0));
+            mWriter.setLayerVisibleRegion(display.get(), layer,
+                                          std::vector<Rect>(1, display.getFrameRect()));
+            mWriter.setLayerZOrder(display.get(), layer, 10);
+            mWriter.setLayerBlendMode(display.get(), layer, BlendMode::NONE);
+            mWriter.setLayerSurfaceDamage(display.get(), layer,
+                                          std::vector<Rect>(1, display.getFrameRect()));
+            mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+            mWriter.setLayerDataspace(display.get(), layer, common::Dataspace::UNKNOWN);
 
-            mWriter->validateDisplay();
+            mWriter.validateDisplay(display.get());
             execute();
-            ASSERT_EQ(0, mReader->mErrors.size());
-            mReader->mCompositionChanges.clear();
+            ASSERT_TRUE(mReader.takeErrors().empty());
 
-            mWriter->presentDisplay();
+            mWriter.presentDisplay(display.get());
             execute();
-            ASSERT_EQ(0, mReader->mErrors.size());
+            ASSERT_TRUE(mReader.takeErrors().empty());
         }
 
         {
             auto buffer = allocate();
             ASSERT_NE(nullptr, buffer->handle);
 
-            mWriter->selectLayer(layer);
-            mWriter->setLayerBuffer(0, buffer->handle, -1);
-            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
-            mWriter->validateDisplay();
+            mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+            mWriter.setLayerSurfaceDamage(display.get(), layer,
+                                          std::vector<Rect>(1, {0, 0, 10, 10}));
+            mWriter.validateDisplay(display.get());
             execute();
-            ASSERT_EQ(0, mReader->mErrors.size());
-            mReader->mCompositionChanges.clear();
+            ASSERT_TRUE(mReader.takeErrors().empty());
 
-            mWriter->presentDisplay();
+            mWriter.presentDisplay(display.get());
             execute();
         }
 
@@ -1411,26 +1396,23 @@
     }};
     // clang-format on
 
-    std::unique_ptr<CommandWriterBase> mWriter;
-    std::unique_ptr<TestCommandReader> mReader;
+    CommandWriterBase mWriter;
+    CommandReaderBase mReader;
 };
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->setColorTransform(kIdentity.data(), ColorTransform::IDENTITY);
+    mWriter.setColorTransform(mPrimaryDisplay, kIdentity.data(), ColorTransform::IDENTITY);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerColorTransform(kIdentity.data());
+    mWriter.setLayerColorTransform(mPrimaryDisplay, layer, kIdentity.data());
     execute();
 
-    if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
-        mReader->mErrors.clear();
+    const auto errors = mReader.takeErrors();
+    if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
         GTEST_SUCCEED() << "setLayerColorTransform is not supported";
         return;
     }
@@ -1440,8 +1422,8 @@
     EXPECT_TRUE(
             mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN, std::vector<Rect>());
+    mWriter.setClientTarget(mPrimaryDisplay, 0, nullptr, -1, Dataspace::UNKNOWN,
+                            std::vector<Rect>());
 
     execute();
 }
@@ -1460,30 +1442,26 @@
                                                kBufferSlotCount, &display)
                         .isOk());
 
-    mWriter->selectDisplay(display.display);
     auto handle = allocate()->handle;
-    mWriter->setOutputBuffer(0, handle, -1);
+    mWriter.setOutputBuffer(display.display, 0, handle, -1);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, VALIDATE_DISPLAY) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->validateDisplay();
+    mWriter.validateDisplay(mPrimaryDisplay);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->validateDisplay();
-    mWriter->acceptDisplayChanges();
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.acceptDisplayChanges(mPrimaryDisplay);
     execute();
 }
 
 // TODO(b/208441745) fix the test failure
 TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->validateDisplay();
-    mWriter->presentDisplay();
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.presentDisplay(mPrimaryDisplay);
     execute();
 }
 
@@ -1503,7 +1481,6 @@
         GTEST_SUCCEED() << "Device does not have skip validate capability, skipping";
         return;
     }
-    mWriter->selectDisplay(mPrimaryDisplay);
     mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
 
     std::vector<RenderIntent> renderIntents;
@@ -1518,37 +1495,39 @@
 
         int64_t layer;
         EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-        mWriter->selectLayer(layer);
-        mWriter->setLayerCompositionType(Composition::DEVICE);
-        mWriter->setLayerDisplayFrame(displayFrame);
-        mWriter->setLayerPlaneAlpha(1);
-        mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
-        mWriter->setLayerTransform(static_cast<Transform>(0));
-        mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
-        mWriter->setLayerZOrder(10);
-        mWriter->setLayerBlendMode(BlendMode::NONE);
-        mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
-        mWriter->setLayerBuffer(0, handle, -1);
-        mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+        mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+        mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+        mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+        mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+                                   {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+        mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+        mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+        mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+        mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+        mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
 
-        mWriter->validateDisplay();
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+        if (!layers.empty()) {
             GTEST_SUCCEED() << "Composition change requested, skipping test";
             return;
         }
 
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->selectLayer(layer);
         auto handle2 = allocate()->handle;
         ASSERT_NE(nullptr, handle2);
-        mWriter->setLayerBuffer(0, handle2, -1);
-        mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
-        mWriter->presentDisplay();
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle2, -1);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, {0, 0, 10, 10}));
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
     }
 }
@@ -1562,33 +1541,37 @@
     ASSERT_NE(nullptr, handle);
     Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerBuffer(0, handle, -1);
-    mWriter->setLayerCompositionType(Composition::CURSOR);
-    mWriter->setLayerDisplayFrame(displayFrame);
-    mWriter->setLayerPlaneAlpha(1);
-    mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
-    mWriter->setLayerTransform(static_cast<Transform>(0));
-    mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
-    mWriter->setLayerZOrder(10);
-    mWriter->setLayerBlendMode(BlendMode::NONE);
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
-    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
-    mWriter->validateDisplay();
+    mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+    mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+    mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+                               {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+    mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
+    mWriter.validateDisplay(mPrimaryDisplay);
 
     execute();
-    if (mReader->mCompositionChanges.size() != 0) {
+    std::vector<int64_t> layers;
+    std::vector<Composition> types;
+    mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+    if (!layers.empty()) {
         GTEST_SUCCEED() << "Composition change requested, skipping test";
         return;
     }
-    mWriter->presentDisplay();
-    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter.presentDisplay(mPrimaryDisplay);
+    ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter->setLayerCursorPosition(1, 1);
-    mWriter->setLayerCursorPosition(0, 0);
-    mWriter->validateDisplay();
-    mWriter->presentDisplay();
+    mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 1, 1);
+    execute();
+
+    mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 0, 0);
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.presentDisplay(mPrimaryDisplay);
     execute();
 }
 
@@ -1598,10 +1581,7 @@
 
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerBuffer(0, handle, -1);
+    mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
     execute();
 }
 
@@ -1612,58 +1592,77 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, empty));
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, unit));
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>());
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerBlendMode(BlendMode::NONE);
-    mWriter->setLayerBlendMode(BlendMode::PREMULTIPLIED);
-    mWriter->setLayerBlendMode(BlendMode::COVERAGE);
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::PREMULTIPLIED);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::COVERAGE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerColor(Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
-                                 static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
-    mWriter->setLayerColor(Color{0, 0, 0, 0});
+    mWriter.setLayerColor(mPrimaryDisplay, layer,
+                          Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+                                static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0});
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerCompositionType(Composition::CLIENT);
-    mWriter->setLayerCompositionType(Composition::DEVICE);
-    mWriter->setLayerCompositionType(Composition::SOLID_COLOR);
-    mWriter->setLayerCompositionType(Composition::CURSOR);
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CLIENT);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::SOLID_COLOR);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DATASPACE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+    mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
     execute();
 }
 
@@ -1671,9 +1670,7 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerDisplayFrame(Rect{0, 0, 1, 1});
+    mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, Rect{0, 0, 1, 1});
     execute();
 }
 
@@ -1681,11 +1678,13 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerPlaneAlpha(0.0f);
-    mWriter->setLayerPlaneAlpha(1.0f);
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 0.0f);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1.0f);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
@@ -1703,9 +1702,7 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerSidebandStream(handle);
+    mWriter.setLayerSidebandStream(mPrimaryDisplay, layer, handle);
     execute();
 }
 
@@ -1713,9 +1710,7 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerSourceCrop(FRect{0.0f, 0.0f, 1.0f, 1.0f});
+    mWriter.setLayerSourceCrop(mPrimaryDisplay, layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
     execute();
 }
 
@@ -1723,19 +1718,41 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerTransform(static_cast<Transform>(0));
-    mWriter->setLayerTransform(Transform::FLIP_H);
-    mWriter->setLayerTransform(Transform::FLIP_V);
-    mWriter->setLayerTransform(Transform::ROT_90);
-    mWriter->setLayerTransform(Transform::ROT_180);
-    mWriter->setLayerTransform(Transform::ROT_270);
-    mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
-                                                      static_cast<int>(Transform::ROT_90)));
-    mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
-                                                      static_cast<int>(Transform::ROT_90)));
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_H);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_V);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_90);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_180);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_270);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer,
+                              static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+                                                     static_cast<int>(Transform::ROT_90)));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer,
+                              static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+                                                     static_cast<int>(Transform::ROT_90)));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_VISIBLE_REGION) {
@@ -1745,32 +1762,36 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerVisibleRegion(std::vector<Rect>(1, empty));
-    mWriter->setLayerVisibleRegion(std::vector<Rect>(1, unit));
-    mWriter->setLayerVisibleRegion(std::vector<Rect>());
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_Z_ORDER) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerZOrder(10);
-    mWriter->setLayerZOrder(0);
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 0);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-
     /**
      * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
      * the D65 white point and the SRGB transfer functions.
@@ -1796,11 +1817,11 @@
     aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
     aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
     aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
-    mWriter->setLayerPerFrameMetadata(aidlMetadata);
+    mWriter.setLayerPerFrameMetadata(mPrimaryDisplay, layer, aidlMetadata);
     execute();
 
-    if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
-        mReader->mErrors.clear();
+    const auto errors = mReader.takeErrors();
+    if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
         GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
         EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
         return;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index 2b058c7..df038db 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -28,7 +28,6 @@
     defaults: ["hidl_defaults"],
     srcs: [
         "GraphicsComposerCallback.cpp",
-        "TestCommandReader.cpp",
         "ReadbackVts.cpp",
         "RenderEngineVts.cpp",
     ],
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
index b612309..a6954b4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
@@ -32,15 +32,14 @@
 const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
                                                            common::Dataspace::DISPLAY_P3};
 
-void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
-    writer->selectLayer(mLayer);
-    writer->setLayerDisplayFrame(mDisplayFrame);
-    writer->setLayerSourceCrop(mSourceCrop);
-    writer->setLayerZOrder(mZOrder);
-    writer->setLayerSurfaceDamage(mSurfaceDamage);
-    writer->setLayerTransform(mTransform);
-    writer->setLayerPlaneAlpha(mAlpha);
-    writer->setLayerBlendMode(mBlendMode);
+void TestLayer::write(CommandWriterBase& writer) {
+    writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
+    writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
+    writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
+    writer.setLayerSurfaceDamage(mDisplay, mLayer, mSurfaceDamage);
+    writer.setLayerTransform(mDisplay, mLayer, mTransform);
+    writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
+    writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
 }
 
 std::string ReadbackHelper::getColorModeString(ColorMode mode) {
@@ -254,10 +253,10 @@
     EXPECT_EQ(::android::OK, status);
 }
 
-void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+void TestColorLayer::write(CommandWriterBase& writer) {
     TestLayer::write(writer);
-    writer->setLayerCompositionType(Composition::SOLID_COLOR);
-    writer->setLayerColor(mColor);
+    writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
+    writer.setLayerColor(mDisplay, mLayer, mColor);
 }
 
 LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
@@ -297,12 +296,12 @@
     setSourceCrop({0, 0, (float)width, (float)height});
 }
 
-void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+void TestBufferLayer::write(CommandWriterBase& writer) {
     TestLayer::write(writer);
-    writer->setLayerCompositionType(mComposition);
-    writer->setLayerVisibleRegion(std::vector<Rect>(1, mDisplayFrame));
+    writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
+    writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
     if (mGraphicBuffer->handle != nullptr)
-        writer->setLayerBuffer(0, mGraphicBuffer->handle, mFillFence);
+        writer.setLayerBuffer(mDisplay, mLayer, 0, mGraphicBuffer->handle, mFillFence);
 }
 
 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
@@ -346,15 +345,12 @@
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
 }
 
-void TestBufferLayer::setDataspace(common::Dataspace dataspace,
-                                   const std::shared_ptr<CommandWriterBase>& writer) {
-    writer->selectLayer(mLayer);
-    writer->setLayerDataspace(dataspace);
+void TestBufferLayer::setDataspace(common::Dataspace dataspace, CommandWriterBase& writer) {
+    writer.setLayerDataspace(mDisplay, mLayer, dataspace);
 }
 
-void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
-    writer->selectLayer(mLayer);
-    writer->setLayerCompositionType(Composition::CLIENT);
+void TestBufferLayer::setToClientComposition(CommandWriterBase& writer) {
+    writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
 }
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
index e83750e..50ce462 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
@@ -86,4 +86,4 @@
     ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
 }
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
deleted file mode 100644
index a5a84d9..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "include/TestCommandReader.h"
-#include <gtest/gtest.h>
-
-namespace aidl::android::hardware::graphics::composer3::vts {
-
-void TestCommandReader::parse() {
-    mErrors.clear();
-    mCompositionChanges.clear();
-    while (!isEmpty()) {
-        int32_t command;
-        uint16_t length;
-        ASSERT_TRUE(beginCommand(&command, &length));
-
-        parseSingleCommand(command, length);
-
-        endCommand();
-    }
-}
-
-void TestCommandReader::parseSingleCommand(int32_t commandRaw, uint16_t length) {
-    auto command = static_cast<Command>(commandRaw);
-
-    switch (command) {
-        case Command::SET_CLIENT_TARGET_PROPERTY: {
-            ASSERT_EQ(2, length);
-            read();
-            close(readFence());
-        } break;
-        case Command::SELECT_DISPLAY: {
-            ASSERT_EQ(2, length);
-            read64();  // display
-        } break;
-        case Command::SET_ERROR: {
-            ASSERT_EQ(2, length);
-            auto loc = read();
-            auto err = readSigned();
-            std::pair<uint32_t, uint32_t> error(loc, err);
-            mErrors.push_back(error);
-        } break;
-        case Command::SET_CHANGED_COMPOSITION_TYPES: {
-            ASSERT_EQ(0, length % 3);
-            for (uint16_t count = 0; count < length / 3; ++count) {
-                uint64_t layerId = read64();
-                uint32_t composition = read();
-
-                std::pair<uint64_t, uint32_t> compositionChange(layerId, composition);
-                mCompositionChanges.push_back(compositionChange);
-            }
-        } break;
-        case Command::SET_DISPLAY_REQUESTS: {
-            ASSERT_EQ(1, length % 3);
-            read();  // displayRequests, ignored for now
-            for (uint16_t count = 0; count < (length - 1) / 3; ++count) {
-                read64();  // layer
-                // silently eat requests to clear the client target, since we won't be testing
-                // client composition anyway
-                ASSERT_EQ(1u, read());
-            }
-        } break;
-        case Command::SET_PRESENT_FENCE: {
-            ASSERT_EQ(1, length);
-            close(readFence());
-        } break;
-        case Command::SET_RELEASE_FENCES: {
-            ASSERT_EQ(0, length % 3);
-            for (uint16_t count = 0; count < length / 3; ++count) {
-                read64();
-                close(readFence());
-            }
-        } break;
-        default:
-            GTEST_FAIL() << "unexpected return command " << std::hex << static_cast<int>(command);
-            break;
-    }
-}
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
index 85b4fdc..d40e3d2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -21,7 +21,6 @@
 #pragma clang diagnostic ignored "-Wconversion"
 
 #include <GraphicsComposerCallback.h>
-#include <TestCommandReader.h>
 #include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/graphics/composer3/command-buffer.h>
@@ -54,7 +53,7 @@
 class TestLayer {
   public:
     TestLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
-        : mComposerClient(client) {
+        : mDisplay(display), mComposerClient(client) {
         client->createLayer(display, kBufferSlotCount, &mLayer);
     }
 
@@ -62,7 +61,7 @@
     // call destroyLayers here
     virtual ~TestLayer(){};
 
-    virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
+    virtual void write(CommandWriterBase& writer);
     virtual LayerSettings toRenderEngineLayerSettings();
 
     void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
@@ -83,7 +82,10 @@
 
     float getAlpha() const { return mAlpha; }
 
+    int64_t getLayer() const { return mLayer; }
+
   protected:
+    int64_t mDisplay;
     int64_t mLayer;
     Rect mDisplayFrame = {0, 0, 0, 0};
     std::vector<Rect> mSurfaceDamage;
@@ -103,7 +105,7 @@
     TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
         : TestLayer{client, display} {}
 
-    void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+    void write(CommandWriterBase& writer) override;
 
     LayerSettings toRenderEngineLayerSettings() override;
 
@@ -121,7 +123,7 @@
                     uint32_t height, common::PixelFormat format,
                     Composition composition = Composition::DEVICE);
 
-    void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+    void write(CommandWriterBase& writer) override;
 
     LayerSettings toRenderEngineLayerSettings() override;
 
@@ -129,9 +131,9 @@
 
     void setBuffer(std::vector<Color> colors);
 
-    void setDataspace(Dataspace dataspace, const std::shared_ptr<CommandWriterBase>& writer);
+    void setDataspace(Dataspace dataspace, CommandWriterBase& writer);
 
-    void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer);
+    void setToClientComposition(CommandWriterBase& writer);
 
     uint32_t getWidth() const { return mWidth; }
 
@@ -211,4 +213,4 @@
     native_handle_t mBufferHandle;
 };
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
index eaff6d7..2798e09 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
@@ -68,4 +68,4 @@
     DisplaySettings mDisplaySettings;
 };
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
deleted file mode 100644
index 852a56e..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <android/hardware/graphics/composer3/command-buffer.h>
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop  // ignored "-Wconversion
-
-namespace aidl::android::hardware::graphics::composer3::vts {
-
-class TestCommandReader : public CommandReaderBase {
-  public:
-    virtual ~TestCommandReader() = default;
-
-    std::vector<std::pair<uint32_t, uint32_t>> mErrors;
-    std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
-
-    // Parse all commands in the return command queue.  Call GTEST_FAIL() for
-    // unexpected errors or commands.
-    void parse();
-    virtual void parseSingleCommand(int32_t commandRaw, uint16_t length);
-};
-}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
index d02cf9c..bdf97ca 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
@@ -19,15 +19,16 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
+#include <unordered_map>
+#include <unordered_set>
 #include <vector>
 
 #include <inttypes.h>
 #include <string.h>
 
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
 #include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
 #include <aidl/android/hardware/graphics/composer3/Color.h>
-#include <aidl/android/hardware/graphics/composer3/Command.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/FloatColor.h>
 #include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
@@ -36,39 +37,29 @@
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
 
+#include <aidl/android/hardware/graphics/composer3/command/CommandPayload.h>
+#include <aidl/android/hardware/graphics/composer3/command/CommandResultPayload.h>
+
 #include <aidl/android/hardware/graphics/common/ColorTransform.h>
 #include <aidl/android/hardware/graphics/common/FRect.h>
 #include <aidl/android/hardware/graphics/common/Rect.h>
 #include <aidl/android/hardware/graphics/common/Transform.h>
 
-#include <fmq/AidlMessageQueue.h>
 #include <log/log.h>
 #include <sync/sync.h>
 
 #include <aidlcommonsupport/NativeHandle.h>
 
+using aidl::android::hardware::graphics::common::BlendMode;
 using aidl::android::hardware::graphics::common::ColorTransform;
 using aidl::android::hardware::graphics::common::Dataspace;
 using aidl::android::hardware::graphics::common::FRect;
 using aidl::android::hardware::graphics::common::Rect;
 using aidl::android::hardware::graphics::common::Transform;
 
-using aidl::android::hardware::graphics::composer3::BlendMode;
-using aidl::android::hardware::graphics::composer3::ClientTargetProperty;
-using aidl::android::hardware::graphics::composer3::Color;
-using aidl::android::hardware::graphics::composer3::Command;
-using aidl::android::hardware::graphics::composer3::Composition;
-using aidl::android::hardware::graphics::composer3::FloatColor;
-using aidl::android::hardware::graphics::composer3::HandleIndex;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadata;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob;
+using namespace aidl::android::hardware::graphics::composer3;
 
 using aidl::android::hardware::common::NativeHandle;
-using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
-using android::AidlMessageQueue;
-using CommandQueueType = AidlMessageQueue<int32_t, SynchronizedReadWrite>;
-using aidl::android::hardware::common::fmq::MQDescriptor;
-using DescriptorType = MQDescriptor<int32_t, SynchronizedReadWrite>;
 
 namespace aidl::android::hardware::graphics::composer3 {
 
@@ -76,820 +67,541 @@
 // units of uint32_t's.
 class CommandWriterBase {
   public:
-    CommandWriterBase(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
-        mData = std::make_unique<int32_t[]>(mDataMaxSize);
-        reset();
-    }
+    CommandWriterBase() { reset(); }
 
     virtual ~CommandWriterBase() { reset(); }
 
     void reset() {
-        mDataWritten = 0;
-        mCommandEnd = 0;
-
-        // handles in mDataHandles are owned by the caller
-        mDataHandles.clear();
-
-        // handles in mTemporaryHandles are owned by the writer
-        for (auto handle : mTemporaryHandles) {
-            native_handle_close(handle);
-            native_handle_delete(handle);
-        }
-        mTemporaryHandles.clear();
+        mDisplayCommand.reset();
+        mLayerCommand.reset();
+        mCommands.clear();
+        mCommandsResults.clear();
     }
 
-    Command getCommand(uint32_t offset) {
-        uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
-        return static_cast<Command>(val & static_cast<uint32_t>(Command::OPCODE_MASK));
+    void setError(int32_t index, int32_t errorCode) {
+        command::Error error;
+        error.commandIndex = index;
+        error.errorCode = errorCode;
+        mCommandsResults.emplace_back(std::move(error));
     }
 
-    bool writeQueue(bool* outQueueChanged, int32_t* outCommandLength,
-                    std::vector<NativeHandle>* outCommandHandles) {
-        if (mDataWritten == 0) {
-            *outQueueChanged = false;
-            *outCommandLength = 0;
-            outCommandHandles->clear();
-            return true;
-        }
-
-        // After data are written to the queue, it may not be read by the
-        // remote reader when
-        //
-        //  - the writer does not send them (because of other errors)
-        //  - the hwbinder transaction fails
-        //  - the reader does not read them (because of other errors)
-        //
-        // Discard the stale data here.
-        size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
-        if (staleDataSize > 0) {
-            ALOGW("discarding stale data from message queue");
-            CommandQueueType::MemTransaction tx;
-            if (mQueue->beginRead(staleDataSize, &tx)) {
-                mQueue->commitRead(staleDataSize);
-            }
-        }
-
-        // write data to queue, optionally resizing it
-        if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
-            if (!mQueue->write(mData.get(), mDataWritten)) {
-                ALOGE("failed to write commands to message queue");
-                return false;
-            }
-
-            *outQueueChanged = false;
-        } else {
-            auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
-            if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
-                ALOGE("failed to prepare a new message queue ");
-                return false;
-            }
-
-            mQueue = std::move(newQueue);
-            *outQueueChanged = true;
-        }
-
-        *outCommandLength = mDataWritten;
-        *outCommandHandles = std::move(mDataHandles);
-
-        return true;
+    void setPresentOrValidateResult(int64_t display, command::PresentOrValidate::Result result) {
+        command::PresentOrValidate presentOrValidate;
+        presentOrValidate.display = display;
+        presentOrValidate.result = result;
+        mCommandsResults.emplace_back(std::move(presentOrValidate));
     }
 
-    DescriptorType getMQDescriptor() const {
-        return (mQueue) ? mQueue->dupeDesc() : DescriptorType{};
-    }
-
-    static constexpr uint16_t kSelectDisplayLength = 2;
-    void selectDisplay(int64_t display) {
-        beginCommand(Command::SELECT_DISPLAY, kSelectDisplayLength);
-        write64(display);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSelectLayerLength = 2;
-    void selectLayer(int64_t layer) {
-        beginCommand(Command::SELECT_LAYER, kSelectLayerLength);
-        write64(layer);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetErrorLength = 2;
-    void setError(uint32_t location, int32_t error) {
-        beginCommand(Command::SET_ERROR, kSetErrorLength);
-        write(location);
-        writeSigned(error);
-        endCommand();
-    }
-
-    static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
-    void setPresentOrValidateResult(uint32_t state) {
-        beginCommand(Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
-                     kPresentOrValidateDisplayResultLength);
-        write(state);
-        endCommand();
-    }
-
-    void setChangedCompositionTypes(const std::vector<int64_t>& layers,
+    void setChangedCompositionTypes(int64_t display, const std::vector<int64_t>& layers,
                                     const std::vector<Composition>& types) {
-        size_t totalLayers = std::min(layers.size(), types.size());
-        size_t currentLayer = 0;
+        command::ChangedCompositionTypes changedCompositionTypes;
+        changedCompositionTypes.display = display;
+        changedCompositionTypes.layers.reserve(layers.size());
+        for (int i = 0; i < layers.size(); i++) {
+            auto layer = command::ChangedCompositionTypes::Layer{.layer = layers[i],
+                                                                 .composition = types[i]};
+            changedCompositionTypes.layers.emplace_back(std::move(layer));
+        }
+        mCommandsResults.emplace_back(std::move(changedCompositionTypes));
+    }
 
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
+    void setDisplayRequests(int64_t display, int32_t displayRequestMask,
+                            const std::vector<int64_t>& layers,
+                            const std::vector<int32_t>& layerRequestMasks) {
+        command::DisplayRequest displayRequest;
+        displayRequest.display = display;
+        displayRequest.mask = displayRequestMask;
+        displayRequest.layerRequests.reserve(layers.size());
+        for (int i = 0; i < layers.size(); i++) {
+            auto layerRequest = command::DisplayRequest::LayerRequest{.layer = layers[i],
+                                                                      .mask = layerRequestMasks[i]};
+            displayRequest.layerRequests.emplace_back(std::move(layerRequest));
+        }
+        mCommandsResults.emplace_back(std::move(displayRequest));
+    }
 
-            beginCommand(Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                writeSigned(static_cast<int32_t>(types[currentLayer + i]));
+    void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) {
+        if (presentFence.get() >= 0) {
+            command::PresentFence presentFenceCommand;
+            presentFenceCommand.fence = std::move(presentFence);
+            presentFenceCommand.display = display;
+            mCommandsResults.emplace_back(std::move(presentFenceCommand));
+        } else {
+            ALOGW("%s: invalid present fence %d", __func__, presentFence.get());
+        }
+    }
+
+    void setReleaseFences(int64_t display, const std::vector<int64_t>& layers,
+                          std::vector<::ndk::ScopedFileDescriptor> releaseFences) {
+        command::ReleaseFences releaseFencesCommand;
+        releaseFencesCommand.display = display;
+        for (int i = 0; i < layers.size(); i++) {
+            if (releaseFences[i].get() >= 0) {
+                command::ReleaseFences::Layer layer;
+                layer.layer = layers[i];
+                layer.fence = std::move(releaseFences[i]);
+                releaseFencesCommand.layers.emplace_back(std::move(layer));
+            } else {
+                ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get());
             }
-            endCommand();
-
-            currentLayer += count;
         }
+        mCommandsResults.emplace_back(std::move(releaseFencesCommand));
     }
 
-    void setDisplayRequests(uint32_t displayRequestMask, const std::vector<int64_t>& layers,
-                            const std::vector<uint32_t>& layerRequestMasks) {
-        size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
-        size_t currentLayer = 0;
+    void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty,
+                                 float whitePointNits) {
+        command::ClientTargetPropertyWithNits clientTargetPropertyWithNits;
+        clientTargetPropertyWithNits.display = display;
+        clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty;
+        clientTargetPropertyWithNits.whitePointNits = whitePointNits;
+        mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits));
+    }
 
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);
+    void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) {
+        command::ColorTransformPayload colorTransformPayload;
+        colorTransformPayload.matrix.assign(matrix, matrix + 16);
+        colorTransformPayload.hint = hint;
+        getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload));
+    }
 
-            beginCommand(Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
-            write(displayRequestMask);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
-            }
-            endCommand();
+    void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
+                         int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
+        command::ClientTarget clientTargetCommand;
+        clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
+        clientTargetCommand.dataspace = dataspace;
+        clientTargetCommand.damage.assign(damage.begin(), damage.end());
+        getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
+    }
 
-            currentLayer += count;
+    void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
+                         int releaseFence) {
+        getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
+                getBuffer(slot, buffer, releaseFence));
+    }
+
+    void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; }
+
+    void presentOrvalidateDisplay(int64_t display) {
+        getDisplayCommand(display).presentOrValidateDisplay = true;
+    }
+
+    void acceptDisplayChanges(int64_t display) {
+        getDisplayCommand(display).acceptDisplayChanges = true;
+    }
+
+    void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }
+
+    void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
+        common::Point cursorPosition;
+        cursorPosition.x = x;
+        cursorPosition.y = y;
+        getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
+    }
+
+    void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
+                        const native_handle_t* buffer, int acquireFence) {
+        getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
+    }
+
+    void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
+        getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
+    }
+
+    void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
+        command::ParcelableBlendMode parcelableBlendMode;
+        parcelableBlendMode.blendMode = mode;
+        getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
+    }
+
+    void setLayerColor(int64_t display, int64_t layer, Color color) {
+        getLayerCommand(display, layer).color.emplace(std::move(color));
+    }
+
+    void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
+        command::ParcelableComposition compositionPayload;
+        compositionPayload.composition = type;
+        getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
+    }
+
+    void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
+        command::ParcelableDataspace dataspacePayload;
+        dataspacePayload.dataspace = dataspace;
+        getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
+    }
+
+    void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
+        getLayerCommand(display, layer).displayFrame.emplace(frame);
+    }
+
+    void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
+        command::PlaneAlpha planeAlpha;
+        planeAlpha.alpha = alpha;
+        getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
+    }
+
+    void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
+        NativeHandle handle;
+        if (stream) handle = ::android::dupToAidl(stream);
+        getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
+    }
+
+    void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
+        getLayerCommand(display, layer).sourceCrop.emplace(crop);
+    }
+
+    void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
+        command::ParcelableTransform transformPayload;
+        transformPayload.transform = transform;
+        getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
+    }
+
+    void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
+        getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
+    }
+
+    void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
+        command::ZOrder zorder;
+        zorder.z = z;
+        getLayerCommand(display, layer).z.emplace(std::move(zorder));
+    }
+
+    void setLayerPerFrameMetadata(int64_t display, int64_t layer,
+                                  const std::vector<PerFrameMetadata>& metadataVec) {
+        getLayerCommand(display, layer)
+                .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
+    }
+
+    void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
+        getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
+    }
+
+    void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
+                                       const std::vector<PerFrameMetadataBlob>& metadata) {
+        getLayerCommand(display, layer)
+                .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
+    }
+
+    void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) {
+        getLayerCommand(display, layer).floatColor.emplace(color);
+    }
+
+    void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key,
+                                 const bool mandatory, const std::vector<uint8_t>& value) {
+        command::GenericMetadata metadata;
+        metadata.key.name = key;
+        metadata.key.mandatory = mandatory;
+        metadata.value.assign(value.begin(), value.end());
+        getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata));
+    }
+
+    const std::vector<command::CommandPayload>& getPendingCommands() {
+        if (mLayerCommand.has_value()) {
+            mCommands.emplace_back(std::move(*mLayerCommand));
+            mLayerCommand.reset();
         }
-    }
-
-    static constexpr uint16_t kSetPresentFenceLength = 1;
-    void setPresentFence(int presentFence) {
-        beginCommand(Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
-        writeFence(presentFence);
-        endCommand();
-    }
-
-    void setReleaseFences(const std::vector<int64_t>& layers,
-                          const std::vector<int>& releaseFences) {
-        size_t totalLayers = std::min(layers.size(), releaseFences.size());
-        size_t currentLayer = 0;
-
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
-
-            beginCommand(Command::SET_RELEASE_FENCES, count * 3);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                writeFence(releaseFences[currentLayer + i]);
-            }
-            endCommand();
-
-            currentLayer += count;
+        if (mDisplayCommand.has_value()) {
+            mCommands.emplace_back(std::move(*mDisplayCommand));
+            mDisplayCommand.reset();
         }
+        return mCommands;
     }
-
-    static constexpr uint16_t kSetColorTransformLength = 17;
-    void setColorTransform(const float* matrix, ColorTransform hint) {
-        beginCommand(Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
-        for (int i = 0; i < 16; i++) {
-            writeFloat(matrix[i]);
-        }
-        writeSigned(static_cast<int32_t>(hint));
-        endCommand();
-    }
-
-    void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
-                         Dataspace dataspace, const std::vector<Rect>& damage) {
-        setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
-                                damage);
-    }
-
-    static constexpr uint16_t kSetOutputBufferLength = 3;
-    void setOutputBuffer(uint32_t slot, const native_handle_t* buffer, int releaseFence) {
-        beginCommand(Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
-        write(slot);
-        writeHandle(buffer, true);
-        writeFence(releaseFence);
-        endCommand();
-    }
-
-    static constexpr uint16_t kValidateDisplayLength = 0;
-    void validateDisplay() {
-        beginCommand(Command::VALIDATE_DISPLAY, kValidateDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
-    void presentOrvalidateDisplay() {
-        beginCommand(Command::PRESENT_OR_VALIDATE_DISPLAY, kPresentOrValidateDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kAcceptDisplayChangesLength = 0;
-    void acceptDisplayChanges() {
-        beginCommand(Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kPresentDisplayLength = 0;
-    void presentDisplay() {
-        beginCommand(Command::PRESENT_DISPLAY, kPresentDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerCursorPositionLength = 2;
-    void setLayerCursorPosition(int32_t x, int32_t y) {
-        beginCommand(Command::SET_LAYER_CURSOR_POSITION, kSetLayerCursorPositionLength);
-        writeSigned(x);
-        writeSigned(y);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerBufferLength = 3;
-    void setLayerBuffer(uint32_t slot, const native_handle_t* buffer, int acquireFence) {
-        beginCommand(Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
-        write(slot);
-        writeHandle(buffer, true);
-        writeFence(acquireFence);
-        endCommand();
-    }
-
-    void setLayerSurfaceDamage(const std::vector<Rect>& damage) {
-        bool doWrite = (damage.size() <= kMaxLength / 4);
-        size_t length = (doWrite) ? damage.size() * 4 : 0;
-
-        beginCommand(Command::SET_LAYER_SURFACE_DAMAGE, length);
-        // When there are too many rectangles in the damage region and doWrite
-        // is false, we write no rectangle at all which means the entire
-        // layer is damaged.
-        if (doWrite) {
-            writeRegion(damage);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerBlendModeLength = 1;
-    void setLayerBlendMode(BlendMode mode) {
-        beginCommand(Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
-        writeSigned(static_cast<int32_t>(mode));
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerColorLength = 1;
-    void setLayerColor(Color color) {
-        beginCommand(Command::SET_LAYER_COLOR, kSetLayerColorLength);
-        writeColor(color);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
-    void setLayerCompositionType(Composition type) {
-        beginCommand(Command::SET_LAYER_COMPOSITION_TYPE, kSetLayerCompositionTypeLength);
-        writeSigned(static_cast<int32_t>(type));
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerDataspaceLength = 1;
-    void setLayerDataspace(Dataspace dataspace) {
-        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
-    }
-
-    static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
-    void setLayerDisplayFrame(const Rect& frame) {
-        beginCommand(Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
-        writeRect(frame);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
-    void setLayerPlaneAlpha(float alpha) {
-        beginCommand(Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
-        writeFloat(alpha);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
-    void setLayerSidebandStream(const native_handle_t* stream) {
-        beginCommand(Command::SET_LAYER_SIDEBAND_STREAM, kSetLayerSidebandStreamLength);
-        writeHandle(stream);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerSourceCropLength = 4;
-    void setLayerSourceCrop(const FRect& crop) {
-        beginCommand(Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
-        writeFRect(crop);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerTransformLength = 1;
-    void setLayerTransform(Transform transform) {
-        beginCommand(Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
-        writeSigned(static_cast<int32_t>(transform));
-        endCommand();
-    }
-
-    void setLayerVisibleRegion(const std::vector<Rect>& visible) {
-        bool doWrite = (visible.size() <= kMaxLength / 4);
-        size_t length = (doWrite) ? visible.size() * 4 : 0;
-
-        beginCommand(Command::SET_LAYER_VISIBLE_REGION, length);
-        // When there are too many rectangles in the visible region and
-        // doWrite is false, we write no rectangle at all which means the
-        // entire layer is visible.
-        if (doWrite) {
-            writeRegion(visible);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerZOrderLength = 1;
-    void setLayerZOrder(uint32_t z) {
-        beginCommand(Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
-        write(z);
-        endCommand();
-    }
-
-    void setLayerPerFrameMetadata(const std::vector<PerFrameMetadata>& metadataVec) {
-        beginCommand(Command::SET_LAYER_PER_FRAME_METADATA, metadataVec.size() * 2);
-        for (const auto& metadata : metadataVec) {
-            writeSigned(static_cast<int32_t>(metadata.key));
-            writeFloat(metadata.value);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerColorTransformLength = 16;
-    void setLayerColorTransform(const float* matrix) {
-        beginCommand(Command::SET_LAYER_COLOR_TRANSFORM, kSetLayerColorTransformLength);
-        for (int i = 0; i < 16; i++) {
-            writeFloat(matrix[i]);
-        }
-        endCommand();
-    }
-
-    void setLayerPerFrameMetadataBlobs(const std::vector<PerFrameMetadataBlob>& metadata) {
-        // in units of uint32_t's
-        size_t commandLength = 0;
-
-        if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
-            LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
-            return;
-        }
-
-        // space for numElements
-        commandLength += 1;
-
-        for (auto metadataBlob : metadata) {
-            commandLength += 1;  // key of metadata blob
-            commandLength += 1;  // size information of metadata blob
-
-            // metadata content size
-            size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
-            commandLength += metadataSize;
-            commandLength +=
-                    (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
-        }
-
-        if (commandLength > std::numeric_limits<uint16_t>::max()) {
-            LOG_FATAL("dynamic metadata size is too large");
-            return;
-        }
-
-        // Blobs are written as:
-        // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
-        uint16_t length = static_cast<uint16_t>(commandLength);
-        beginCommand(Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
-        write(static_cast<uint32_t>(metadata.size()));
-        for (auto metadataBlob : metadata) {
-            writeSigned(static_cast<int32_t>(metadataBlob.key));
-            write(static_cast<uint32_t>(metadataBlob.blob.size()));
-            writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerFloatColorLength = 4;
-    void setLayerFloatColor(FloatColor color) {
-        beginCommand(Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
-        writeFloatColor(color);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetClientTargetPropertyLength = 2;
-    void setClientTargetProperty(const ClientTargetProperty& clientTargetProperty) {
-        beginCommand(Command::SET_CLIENT_TARGET_PROPERTY, kSetClientTargetPropertyLength);
-        writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat));
-        writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
-        endCommand();
-    }
-
-    void setLayerGenericMetadata(const std::string& key, const bool mandatory,
-                                 const std::vector<uint8_t>& value) {
-        const size_t commandSize = 3 + sizeToElements(key.size()) + sizeToElements(value.size());
-        if (commandSize > std::numeric_limits<uint16_t>::max()) {
-            LOG_FATAL("Too much generic metadata (%zu elements)", commandSize);
-            return;
-        }
-
-        beginCommand(Command::SET_LAYER_GENERIC_METADATA, static_cast<uint16_t>(commandSize));
-        write(key.size());
-        writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
-        write(mandatory);
-        write(value.size());
-        writeBlob(value.size(), value.data());
-        endCommand();
+    std::vector<command::CommandResultPayload> getPendingCommandResults() {
+        return std::move(mCommandsResults);
     }
 
   protected:
-    template <typename T>
-    void beginCommand(T command, uint16_t length) {
-        beginCommandBase(static_cast<Command>(command), length);
+    command::Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
+        command::Buffer bufferCommand;
+        bufferCommand.slot = slot;
+        if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
+        if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
+        return bufferCommand;
     }
 
-    void setClientTargetInternal(uint32_t slot, const native_handle_t* target, int acquireFence,
-                                 int32_t dataspace, const std::vector<Rect>& damage) {
-        bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
-        size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
-
-        beginCommand(Command::SET_CLIENT_TARGET, length);
-        write(slot);
-        writeHandle(target, true);
-        writeFence(acquireFence);
-        writeSigned(dataspace);
-        // When there are too many rectangles in the damage region and doWrite
-        // is false, we write no rectangle at all which means the entire
-        // client target is damaged.
-        if (doWrite) {
-            writeRegion(damage);
-        }
-        endCommand();
-    }
-
-    void setLayerDataspaceInternal(int32_t dataspace) {
-        beginCommand(Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
-        writeSigned(dataspace);
-        endCommand();
-    }
-
-    void beginCommandBase(Command command, uint16_t length) {
-        if (mCommandEnd) {
-            LOG_FATAL("endCommand was not called before command 0x%x", command);
-        }
-
-        growData(1 + length);
-        write(static_cast<uint32_t>(command) | length);
-
-        mCommandEnd = mDataWritten + length;
-    }
-
-    void endCommand() {
-        if (!mCommandEnd) {
-            LOG_FATAL("beginCommand was not called");
-        } else if (mDataWritten > mCommandEnd) {
-            LOG_FATAL("too much data written");
-            mDataWritten = mCommandEnd;
-        } else if (mDataWritten < mCommandEnd) {
-            LOG_FATAL("too little data written");
-            while (mDataWritten < mCommandEnd) {
-                write(0);
-            }
-        }
-
-        mCommandEnd = 0;
-    }
-
-    void write(uint32_t val) { mData[mDataWritten++] = val; }
-
-    void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
-    void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
-    void write64(uint64_t val) {
-        uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
-        uint32_t hi = static_cast<uint32_t>(val >> 32);
-        write(lo);
-        write(hi);
-    }
-
-    void writeRect(const Rect& rect) {
-        writeSigned(rect.left);
-        writeSigned(rect.top);
-        writeSigned(rect.right);
-        writeSigned(rect.bottom);
-    }
-
-    void writeRegion(const std::vector<Rect>& region) {
-        for (const auto& rect : region) {
-            writeRect(rect);
-        }
-    }
-
-    void writeFRect(const FRect& rect) {
-        writeFloat(rect.left);
-        writeFloat(rect.top);
-        writeFloat(rect.right);
-        writeFloat(rect.bottom);
-    }
-
-    void writeColor(const Color& color) {
-        write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24));
-    }
-
-    void writeFloatColor(const FloatColor& color) {
-        writeFloat(color.r);
-        writeFloat(color.g);
-        writeFloat(color.b);
-        writeFloat(color.a);
-    }
-
-    void writeBlob(uint32_t length, const unsigned char* blob) {
-        memcpy(&mData[mDataWritten], blob, length);
-        uint32_t numElements = length / 4;
-        mDataWritten += numElements;
-        mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
-    }
-
-    // ownership of handle is not transferred
-    void writeHandle(const native_handle_t* handle, bool useCache) {
-        if (!handle) {
-            writeSigned(
-                    static_cast<int32_t>((useCache) ? HandleIndex::CACHED : HandleIndex::EMPTY));
-            return;
-        }
-
-        mDataHandles.push_back(::android::dupToAidl(handle));
-        writeSigned(mDataHandles.size() - 1);
-    }
-
-    void writeHandle(const native_handle_t* handle) { writeHandle(handle, false); }
-
-    // ownership of fence is transferred
-    void writeFence(int fence) {
-        native_handle_t* handle = nullptr;
-        if (fence >= 0) {
-            handle = getTemporaryHandle(1, 0);
-            if (handle) {
-                handle->data[0] = fence;
-            } else {
-                ALOGW("failed to get temporary handle for fence %d", fence);
-                sync_wait(fence, -1);
-                close(fence);
-            }
-        }
-
-        writeHandle(handle);
-    }
-
-    native_handle_t* getTemporaryHandle(int numFds, int numInts) {
-        native_handle_t* handle = native_handle_create(numFds, numInts);
-        if (handle) {
-            mTemporaryHandles.push_back(handle);
-        }
-        return handle;
-    }
-
-    static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
-
-    std::unique_ptr<int32_t[]> mData;
-    uint32_t mDataWritten;
+    std::optional<command::DisplayCommand> mDisplayCommand;
+    std::optional<command::LayerCommand> mLayerCommand;
+    std::vector<command::CommandPayload> mCommands;
+    std::vector<command::CommandResultPayload> mCommandsResults;
 
   private:
-    void growData(uint32_t grow) {
-        uint32_t newWritten = mDataWritten + grow;
-        if (newWritten < mDataWritten) {
-            LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32 ", growing by %" PRIu32,
-                             mDataWritten, grow);
-        }
+    // std::vector<native_handle_t*> mTemporaryHandles;
 
-        if (newWritten <= mDataMaxSize) {
-            return;
+    command::DisplayCommand& getDisplayCommand(int64_t display) {
+        if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
+            if (mDisplayCommand.has_value()) mCommands.emplace_back(std::move(*mDisplayCommand));
+            mDisplayCommand.emplace();
+            mDisplayCommand->display = display;
+            return *mDisplayCommand;
         }
-
-        uint32_t newMaxSize = mDataMaxSize << 1;
-        if (newMaxSize < newWritten) {
-            newMaxSize = newWritten;
-        }
-
-        auto newData = std::make_unique<int32_t[]>(newMaxSize);
-        std::copy_n(mData.get(), mDataWritten, newData.get());
-        mDataMaxSize = newMaxSize;
-        mData = std::move(newData);
+        return *mDisplayCommand;
     }
 
-    uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
-
-    uint32_t mDataMaxSize;
-    // end offset of the current command
-    uint32_t mCommandEnd;
-
-    std::vector<NativeHandle> mDataHandles;
-    std::vector<native_handle_t*> mTemporaryHandles;
-
-    std::unique_ptr<CommandQueueType> mQueue;
+    command::LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
+        if (!mLayerCommand.has_value() || mLayerCommand->display != display ||
+            mLayerCommand->layer != layer) {
+            if (mLayerCommand.has_value()) mCommands.emplace_back(std::move(*mLayerCommand));
+            mLayerCommand.emplace();
+            mLayerCommand->display = display;
+            mLayerCommand->layer = layer;
+            return *mLayerCommand;
+        }
+        return *mLayerCommand;
+    }
 };
 
-// This class helps parse a command queue.  Note that all sizes/lengths are in
-// units of uint32_t's.
 class CommandReaderBase {
   public:
-    CommandReaderBase() : mDataMaxSize(0) { reset(); }
+    ~CommandReaderBase() { resetData(); }
 
-    bool setMQDescriptor(const DescriptorType& descriptor) {
-        mQueue = std::make_unique<CommandQueueType>(descriptor, false);
-        if (mQueue->isValid()) {
-            return true;
-        } else {
-            mQueue = nullptr;
-            return false;
+    // Parse and execute commands from the command queue.  The commands are
+    // actually return values from the server and will be saved in ReturnData.
+    void parse(const std::vector<command::CommandResultPayload>& results) {
+        resetData();
+
+        for (const auto& result : results) {
+            switch (result.getTag()) {
+                case command::CommandResultPayload::Tag::error:
+                    parseSetError(result.get<command::CommandResultPayload::Tag::error>());
+                    break;
+                case command::CommandResultPayload::Tag::changedCompositionType:
+                    parseSetChangedCompositionTypes(
+                            result.get<
+                                    command::CommandResultPayload::Tag::changedCompositionType>());
+                    break;
+                case command::CommandResultPayload::Tag::displayRequest:
+                    parseSetDisplayRequests(
+                            result.get<command::CommandResultPayload::Tag::displayRequest>());
+                    break;
+                case command::CommandResultPayload::Tag::presentFence:
+                    parseSetPresentFence(
+                            result.get<command::CommandResultPayload::Tag::presentFence>());
+                    break;
+                case command::CommandResultPayload::Tag::releaseFences:
+                    parseSetReleaseFences(
+                            result.get<command::CommandResultPayload::Tag::releaseFences>());
+                    break;
+                case command::CommandResultPayload::Tag::presentOrValidateResult:
+                    parseSetPresentOrValidateDisplayResult(
+                            result.get<
+                                    command::CommandResultPayload::Tag::presentOrValidateResult>());
+                    break;
+                case command::CommandResultPayload::Tag::clientTargetProperty:
+                    parseSetClientTargetProperty(
+                            result.get<command::CommandResultPayload::Tag::clientTargetProperty>());
+                    break;
+            }
         }
     }
 
-    bool readQueue(int32_t commandLength, std::vector<NativeHandle> commandHandles) {
-        if (!mQueue) {
+    std::vector<command::Error> takeErrors() { return std::move(mErrors); }
+
+    bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
+                    uint32_t* outNumLayerRequestMasks) const {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outNumChangedCompositionTypes = 0;
+            *outNumLayerRequestMasks = 0;
             return false;
         }
 
-        auto quantumCount = mQueue->getQuantumCount();
-        if (mDataMaxSize < quantumCount) {
-            mDataMaxSize = quantumCount;
-            mData = std::make_unique<int32_t[]>(mDataMaxSize);
+        const ReturnData& data = found->second;
+
+        *outNumChangedCompositionTypes = static_cast<uint32_t>(data.compositionTypes.size());
+        *outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size());
+
+        return !(data.compositionTypes.empty() && data.requestMasks.empty());
+    }
+
+    // Get and clear saved changed composition types.
+    void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers,
+                                     std::vector<Composition>* outTypes) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            outLayers->clear();
+            outTypes->clear();
+            return;
         }
 
-        if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
-            ALOGE("failed to read commands from message queue");
-            return false;
+        ReturnData& data = found->second;
+
+        *outLayers = std::move(data.changedLayers);
+        *outTypes = std::move(data.compositionTypes);
+    }
+
+    // Get and clear saved display requests.
+    void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask,
+                             std::vector<int64_t>* outLayers,
+                             std::vector<uint32_t>* outLayerRequestMasks) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outDisplayRequestMask = 0;
+            outLayers->clear();
+            outLayerRequestMasks->clear();
+            return;
         }
 
-        mDataSize = commandLength;
-        mDataRead = 0;
-        mCommandBegin = 0;
-        mCommandEnd = 0;
-        mDataHandles = std::move(commandHandles);
-        return true;
+        ReturnData& data = found->second;
+
+        *outDisplayRequestMask = data.displayRequests;
+        *outLayers = std::move(data.requestedLayers);
+        *outLayerRequestMasks = std::move(data.requestMasks);
     }
 
-    void reset() {
-        mDataSize = 0;
-        mDataRead = 0;
-        mCommandBegin = 0;
-        mCommandEnd = 0;
-        mDataHandles.clear();
-    }
-
-  protected:
-    template <typename T>
-    bool beginCommand(T* outCommand, uint16_t* outLength) {
-        return beginCommandBase(reinterpret_cast<Command*>(outCommand), outLength);
-    }
-
-    bool isEmpty() const { return (mDataRead >= mDataSize); }
-
-    bool beginCommandBase(Command* outCommand, uint16_t* outLength) {
-        if (mCommandEnd) {
-            LOG_FATAL("endCommand was not called for last command");
+    // Get and clear saved release fences.
+    void takeReleaseFences(int64_t display, std::vector<int64_t>* outLayers,
+                           std::vector<int>* outReleaseFences) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            outLayers->clear();
+            outReleaseFences->clear();
+            return;
         }
 
-        constexpr uint32_t opcode_mask = static_cast<uint32_t>(Command::OPCODE_MASK);
-        constexpr uint32_t length_mask = static_cast<uint32_t>(Command::LENGTH_MASK);
+        ReturnData& data = found->second;
 
-        uint32_t val = read();
-        *outCommand = static_cast<Command>(val & opcode_mask);
-        *outLength = static_cast<uint16_t>(val & length_mask);
+        *outLayers = std::move(data.releasedLayers);
+        *outReleaseFences = std::move(data.releaseFences);
+    }
 
-        if (mDataRead + *outLength > mDataSize) {
-            ALOGE("command 0x%x has invalid command length %" PRIu16, *outCommand, *outLength);
-            // undo the read() above
-            mDataRead--;
-            return false;
+    // Get and clear saved present fence.
+    void takePresentFence(int64_t display, int* outPresentFence) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outPresentFence = -1;
+            return;
         }
 
-        mCommandEnd = mDataRead + *outLength;
+        ReturnData& data = found->second;
 
-        return true;
+        *outPresentFence = data.presentFence;
+        data.presentFence = -1;
     }
 
-    void endCommand() {
-        if (!mCommandEnd) {
-            LOG_FATAL("beginCommand was not called");
-        } else if (mDataRead > mCommandEnd) {
-            LOG_FATAL("too much data read");
-            mDataRead = mCommandEnd;
-        } else if (mDataRead < mCommandEnd) {
-            LOG_FATAL("too little data read");
-            mDataRead = mCommandEnd;
+    // Get what stage succeeded during PresentOrValidate: Present or Validate
+    void takePresentOrValidateStage(int64_t display, uint32_t* state) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *state = static_cast<uint32_t>(-1);
+            return;
+        }
+        ReturnData& data = found->second;
+        *state = data.presentOrValidateState;
+    }
+
+    // Get the client target properties requested by hardware composer.
+    void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty) {
+        auto found = mReturnData.find(display);
+
+        // If not found, return the default values.
+        if (found == mReturnData.end()) {
+            outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888;
+            outClientTargetProperty->dataspace = Dataspace::UNKNOWN;
+            return;
         }
 
-        mCommandBegin = mCommandEnd;
-        mCommandEnd = 0;
+        ReturnData& data = found->second;
+        *outClientTargetProperty = data.clientTargetProperty;
     }
 
-    uint32_t getCommandLoc() const { return mCommandBegin; }
-
-    uint32_t read() { return mData[mDataRead++]; }
-
-    int32_t readSigned() {
-        int32_t val;
-        memcpy(&val, &mData[mDataRead++], sizeof(val));
-        return val;
-    }
-
-    float readFloat() {
-        float val;
-        memcpy(&val, &mData[mDataRead++], sizeof(val));
-        return val;
-    }
-
-    uint64_t read64() {
-        uint32_t lo = read();
-        uint32_t hi = read();
-        return (static_cast<uint64_t>(hi) << 32) | lo;
-    }
-
-    Color readColor() {
-        uint32_t val = read();
-        return Color{
-                static_cast<int8_t>((val >> 0) & 0xff),
-                static_cast<int8_t>((val >> 8) & 0xff),
-                static_cast<int8_t>((val >> 16) & 0xff),
-                static_cast<int8_t>((val >> 24) & 0xff),
-        };
-    }
-
-    // ownership of handle is not transferred
-    const native_handle_t* readHandle(bool* outUseCache) {
-        const native_handle_t* handle = nullptr;
-
-        int32_t index = readSigned();
-        switch (index) {
-            case static_cast<int32_t>(HandleIndex::EMPTY):
-                *outUseCache = false;
-                break;
-            case static_cast<int32_t>(HandleIndex::CACHED):
-                *outUseCache = true;
-                break;
-            default:
-                if (static_cast<size_t>(index) < mDataHandles.size()) {
-                    handle = ::android::makeFromAidl(mDataHandles[index]);
-                } else {
-                    ALOGE("invalid handle index %zu", static_cast<size_t>(index));
-                }
-                *outUseCache = false;
-                break;
-        }
-
-        return handle;
-    }
-
-    const native_handle_t* readHandle() {
-        bool useCache;
-        return readHandle(&useCache);
-    }
-
-    // ownership of fence is transferred
-    int readFence() {
-        auto handle = readHandle();
-        if (!handle || handle->numFds == 0) {
-            return -1;
-        }
-
-        if (handle->numFds != 1) {
-            ALOGE("invalid fence handle with %d fds", handle->numFds);
-            return -1;
-        }
-
-        int fd = dup(handle->data[0]);
-        if (fd < 0) {
-            ALOGW("failed to dup fence %d", handle->data[0]);
-            sync_wait(handle->data[0], -1);
-            fd = -1;
-        }
-
-        return fd;
-    }
-
-    std::unique_ptr<int32_t[]> mData;
-    uint32_t mDataRead;
-
   private:
-    std::unique_ptr<CommandQueueType> mQueue;
-    uint32_t mDataMaxSize;
+    void resetData() {
+        mErrors.clear();
 
-    uint32_t mDataSize;
+        for (auto& data : mReturnData) {
+            if (data.second.presentFence >= 0) {
+                close(data.second.presentFence);
+            }
+            for (auto fence : data.second.releaseFences) {
+                if (fence >= 0) {
+                    close(fence);
+                }
+            }
+        }
 
-    // begin/end offsets of the current command
-    uint32_t mCommandBegin;
-    uint32_t mCommandEnd;
+        mReturnData.clear();
+    }
 
-    std::vector<NativeHandle> mDataHandles;
+    void parseSetError(const command::Error& error) { mErrors.emplace_back(error); }
+
+    void parseSetChangedCompositionTypes(
+            const command::ChangedCompositionTypes& changedCompositionTypes) {
+        auto& data = mReturnData[changedCompositionTypes.display];
+
+        data.changedLayers.reserve(changedCompositionTypes.layers.size());
+        data.compositionTypes.reserve(changedCompositionTypes.layers.size());
+        for (const auto& layer : changedCompositionTypes.layers) {
+            data.changedLayers.push_back(layer.layer);
+            data.compositionTypes.push_back(layer.composition);
+        }
+    }
+
+    void parseSetDisplayRequests(const command::DisplayRequest& displayRequest) {
+        auto& data = mReturnData[displayRequest.display];
+
+        data.displayRequests = displayRequest.mask;
+        data.requestedLayers.reserve(displayRequest.layerRequests.size());
+        data.requestMasks.reserve(displayRequest.layerRequests.size());
+        for (const auto& layerRequest : displayRequest.layerRequests) {
+            data.requestedLayers.push_back(layerRequest.layer);
+            data.requestMasks.push_back(layerRequest.mask);
+        }
+    }
+
+    void parseSetPresentFence(const command::PresentFence& presentFence) {
+        auto& data = mReturnData[presentFence.display];
+        if (data.presentFence >= 0) {
+            close(data.presentFence);
+        }
+        data.presentFence = dup(presentFence.fence.get());
+    }
+
+    void parseSetReleaseFences(const command::ReleaseFences& releaseFences) {
+        auto& data = mReturnData[releaseFences.display];
+        data.releasedLayers.reserve(releaseFences.layers.size());
+        data.releaseFences.reserve(releaseFences.layers.size());
+        for (const auto& layer : releaseFences.layers) {
+            data.releasedLayers.push_back(layer.layer);
+            data.releaseFences.push_back(dup(layer.fence.get()));
+        }
+    }
+
+    void parseSetPresentOrValidateDisplayResult(
+            const command::PresentOrValidate& presentOrValidate) {
+        auto& data = mReturnData[presentOrValidate.display];
+        data.presentOrValidateState =
+                presentOrValidate.result == command::PresentOrValidate::Result::Presented ? 1 : 0;
+    }
+
+    void parseSetClientTargetProperty(
+            const command::ClientTargetPropertyWithNits& clientTargetProperty) {
+        auto& data = mReturnData[clientTargetProperty.display];
+        data.clientTargetProperty.pixelFormat =
+                clientTargetProperty.clientTargetProperty.pixelFormat;
+        data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace;
+    }
+
+    struct ReturnData {
+        int32_t displayRequests = 0;
+
+        std::vector<int64_t> changedLayers;
+        std::vector<Composition> compositionTypes;
+
+        std::vector<int64_t> requestedLayers;
+        std::vector<uint32_t> requestMasks;
+
+        int presentFence = -1;
+
+        std::vector<int64_t> releasedLayers;
+        std::vector<int> releaseFences;
+
+        uint32_t presentOrValidateState;
+
+        ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
+                                                  Dataspace::UNKNOWN};
+    };
+
+    std::vector<command::Error> mErrors;
+    std::unordered_map<int64_t, ReturnData> mReturnData;
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
index c892863..7004955 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
@@ -17,25 +17,22 @@
 #pragma once
 
 #include <limits>
+#include "aidl/android/hardware/graphics/common/BlendMode.h"
 #include "aidl/android/hardware/graphics/common/FRect.h"
 #include "aidl/android/hardware/graphics/common/Rect.h"
-#include "aidl/android/hardware/graphics/composer3/BlendMode.h"
 #include "aidl/android/hardware/graphics/composer3/Capability.h"
 #include "aidl/android/hardware/graphics/composer3/ClientTargetProperty.h"
 #include "aidl/android/hardware/graphics/composer3/Color.h"
-#include "aidl/android/hardware/graphics/composer3/Command.h"
 #include "aidl/android/hardware/graphics/composer3/Composition.h"
 #include "aidl/android/hardware/graphics/composer3/ContentType.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayAttribute.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayCapability.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayConnectionType.h"
-#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
 #include "aidl/android/hardware/graphics/composer3/FloatColor.h"
 #include "aidl/android/hardware/graphics/composer3/FormatColorComponent.h"
 #include "aidl/android/hardware/graphics/composer3/HandleIndex.h"
 #include "aidl/android/hardware/graphics/composer3/IComposer.h"
 #include "aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.h"
-#include "aidl/android/hardware/graphics/composer3/LayerRequest.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadata.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.h"