Merge "Wifi: Set wlan.driver.status to 'ok' when ready"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 531e44e..fcaced0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -66,3 +66,5 @@
 $(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore\@1\.1*" -print0 | xargs -0 rm -f)
 $(call add-clean-step, find $(PRODUCT_OUT)/system $(PRODUCT_OUT)/vendor -type f -name "android\.hardware\.configstore*" -print0 | xargs -0 rm -f)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/seccomp_policy/configstore@1.0.policy)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/seccomp_policy/configstore@1.1.policy)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.configstore@1.1-service)
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 917fbc3..74bbfb4 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -36,6 +36,8 @@
 constexpr int DOOR_1_RIGHT = (int)VehicleAreaDoor::ROW_1_RIGHT;
 constexpr int DOOR_2_LEFT = (int)VehicleAreaDoor::ROW_2_LEFT;
 constexpr int DOOR_2_RIGHT = (int)VehicleAreaDoor::ROW_2_RIGHT;
+constexpr int FAN_DIRECTION_FACE = (int)VehicleHvacFanDirection::FACE;
+constexpr int FAN_DIRECTION_FLOOR = (int)VehicleHvacFanDirection::FLOOR;
 constexpr int OBD2_LIVE_FRAME = (int)VehicleProperty::OBD2_LIVE_FRAME;
 constexpr int OBD2_FREEZE_FRAME = (int)VehicleProperty::OBD2_FREEZE_FRAME;
 constexpr int OBD2_FREEZE_FRAME_INFO = (int)VehicleProperty::OBD2_FREEZE_FRAME_INFO;
@@ -46,6 +48,8 @@
 constexpr int ALL_WHEELS =
     (int)(VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT |
           VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR);
+constexpr int SEAT_1_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT);
+constexpr int SEAT_1_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT);
 constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT |
                                 VehicleAreaSeat::ROW_2_CENTER);
 constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT);
@@ -58,6 +62,14 @@
     (int)(0x103 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::INT32 | VehicleArea::WINDOW);
 constexpr int VENDOR_EXTENSION_STRING_PROPERTY =
     (int)(0x104 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::STRING | VehicleArea::GLOBAL);
+constexpr int FUEL_DOOR_REAR_LEFT = (int)PortLocationType::REAR_LEFT;
+constexpr int CHARGE_PORT_FRONT_LEFT = (int)PortLocationType::FRONT_LEFT;
+constexpr int LIGHT_STATE_ON = (int)VehicleLightState::ON;
+constexpr int LIGHT_SWITCH_AUTO = (int)VehicleLightSwitch::AUTOMATIC;
+constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT;
+constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT;
+constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR;
+constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR;
 
 /**
  * This property is used for test purpose to generate fake events. Here is the test package that
@@ -149,8 +161,9 @@
              .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::STATIC,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
-     .initialValue = {.floatValues = {15000}}},
+     .initialValue = {.floatValues = {15000.0f}}},
 
     {.config =
          {
@@ -165,8 +178,9 @@
              .prop = toInt(VehicleProperty::INFO_EV_BATTERY_CAPACITY),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::STATIC,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
-     .initialValue = {.floatValues = {150000}}},
+     .initialValue = {.floatValues = {150000.0f}}},
 
     {.config =
          {
@@ -178,6 +192,24 @@
 
     {.config =
          {
+             .prop = toInt(VehicleProperty::INFO_FUEL_DOOR_LOCATION),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::STATIC,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {FUEL_DOOR_REAR_LEFT}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::INFO_EV_PORT_LOCATION),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::STATIC,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {CHARGE_PORT_FRONT_LEFT}}},
+
+    {.config =
+         {
              .prop = toInt(VehicleProperty::INFO_MAKE),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::STATIC,
@@ -218,14 +250,16 @@
              .prop = toInt(VehicleProperty::FUEL_LEVEL),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
-     .initialValue = {.floatValues = {15000}}},
+     .initialValue = {.floatValues = {15000.0f}}},
 
     {.config =
          {
              .prop = toInt(VehicleProperty::FUEL_DOOR_OPEN),
-             .access = VehiclePropertyAccess::READ,
+             .access = VehiclePropertyAccess::READ_WRITE,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
      .initialValue = {.int32Values = {0}}},
 
@@ -234,14 +268,16 @@
              .prop = toInt(VehicleProperty::EV_BATTERY_LEVEL),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
-     .initialValue = {.floatValues = {150000}}},
+     .initialValue = {.floatValues = {150000.0f}}},
 
     {.config =
          {
              .prop = toInt(VehicleProperty::EV_CHARGE_PORT_OPEN),
-             .access = VehiclePropertyAccess::READ,
+             .access = VehiclePropertyAccess::READ_WRITE,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
      .initialValue = {.int32Values = {0}}},
 
@@ -250,6 +286,7 @@
              .prop = toInt(VehicleProperty::EV_CHARGE_PORT_CONNECTED),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
      .initialValue = {.int32Values = {0}}},
 
@@ -258,8 +295,37 @@
              .prop = toInt(VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
-     .initialValue = {.floatValues = {0}}},
+     .initialValue = {.floatValues = {0.0f}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::RANGE_REMAINING),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.floatValues = {100.0f}}},  // units in meters
+
+    {.config =
+         {.prop = toInt(VehicleProperty::TIRE_PRESSURE),
+          .access = VehiclePropertyAccess::READ,
+          .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+          .areaConfigs =
+              {VehicleAreaConfig{
+                   .areaId = WHEEL_FRONT_LEFT, .minFloatValue = 100.0f, .maxFloatValue = 300.0f,
+               },
+               VehicleAreaConfig{
+                   .areaId = WHEEL_FRONT_RIGHT, .minFloatValue = 100.0f, .maxFloatValue = 300.0f,
+               },
+               VehicleAreaConfig{
+                   .areaId = WHEEL_REAR_LEFT, .minFloatValue = 100.0f, .maxFloatValue = 300.0f,
+               },
+               VehicleAreaConfig{
+                   .areaId = WHEEL_REAR_RIGHT, .minFloatValue = 100.0f, .maxFloatValue = 300.0f,
+               }}},
+     .initialValue = {.floatValues = {200}}},  // units in kPa
 
     {.config =
          {
@@ -282,6 +348,7 @@
              .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
              .access = VehiclePropertyAccess::READ,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
          },
      .initialValue = {.int32Values = {0}}},
 
@@ -371,6 +438,24 @@
                 .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
      .initialValue = {.int32Values = {toInt(VehicleHvacFanDirection::FACE)}}},
 
+    {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE),
+                .access = VehiclePropertyAccess::READ,
+                .changeMode = VehiclePropertyChangeMode::STATIC,
+                .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
+     .initialValue = {.int32Values = {FAN_DIRECTION_FACE, FAN_DIRECTION_FLOOR,
+                                      FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR}}},
+
+    {.config = {.prop = toInt(VehicleProperty::HVAC_SEAT_VENTILATION),
+                .access = VehiclePropertyAccess::READ_WRITE,
+                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                .areaConfigs = {VehicleAreaConfig{
+                                    .areaId = SEAT_1_LEFT, .minInt32Value = 0, .maxInt32Value = 3,
+                                },
+                                VehicleAreaConfig{
+                                    .areaId = SEAT_1_RIGHT, .minInt32Value = 0, .maxInt32Value = 3,
+                                }}},
+     .initialValue = {.int32Values = {0}}},  // 0 is off and +ve values indicate ventilation level.
+
     {.config = {.prop = toInt(VehicleProperty::HVAC_STEERING_WHEEL_HEAT),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -378,6 +463,17 @@
                     .areaId = (0), .minInt32Value = -2, .maxInt32Value = 2}}},
      .initialValue = {.int32Values = {0}}},  // +ve values for heating and -ve for cooling
 
+    {.config = {.prop = toInt(VehicleProperty::HVAC_SEAT_TEMPERATURE),
+                .access = VehiclePropertyAccess::READ_WRITE,
+                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                .areaConfigs = {VehicleAreaConfig{
+                                    .areaId = SEAT_1_LEFT, .minInt32Value = -2, .maxInt32Value = 2,
+                                },
+                                VehicleAreaConfig{
+                                    .areaId = SEAT_1_RIGHT, .minInt32Value = -2, .maxInt32Value = 2,
+                                }}},
+     .initialValue = {.int32Values = {0}}},  // +ve values for heating and -ve for cooling
+
     {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -540,6 +636,78 @@
                    .configArray = {1}},
     },
 
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::HEADLIGHTS_STATE),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::HIGH_BEAM_LIGHTS_STATE),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::FOG_LIGHTS_STATE),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::HAZARD_LIGHTS_STATE),
+             .access = VehiclePropertyAccess::READ,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::HEADLIGHTS_SWITCH),
+             .access = VehiclePropertyAccess::READ_WRITE,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH),
+             .access = VehiclePropertyAccess::READ_WRITE,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::FOG_LIGHTS_SWITCH),
+             .access = VehiclePropertyAccess::READ_WRITE,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::HAZARD_LIGHTS_SWITCH),
+             .access = VehiclePropertyAccess::READ_WRITE,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+         },
+     .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+
     {.config = {.prop = VEHICLE_MAP_SERVICE,
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE}},
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 8803cdd..b9cb093 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -105,7 +105,7 @@
     </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.configstore</name>
-        <version>1.1</version>
+        <version>1.2</version>
         <interface>
             <name>ISurfaceFlingerConfigs</name>
             <instance>default</instance>
diff --git a/configstore/1.0/ISurfaceFlingerConfigs.hal b/configstore/1.0/ISurfaceFlingerConfigs.hal
index 5f975bd..0790905 100644
--- a/configstore/1.0/ISurfaceFlingerConfigs.hal
+++ b/configstore/1.0/ISurfaceFlingerConfigs.hal
@@ -61,11 +61,16 @@
     hasWideColorDisplay() generates (OptionalBool value);
 
     /**
-     * hwHdrDisplay indicates that the device has
-     * or can support an HDR (High Dynamic Range) display.
-     * Typically an HDR display is also wide-color.
+     * hwHdrDisplay indicates that the device has an High Dynamic Range display.
+     * A display is considered High Dynamic Range if it
+     *
+     *     1. is a wide color gamut display, typically DCI-P3 or lager
+     *     2. has high luminance capability, typically 540 nits or higher at 10% OPR
+     *
      * Indicate support for this feature by setting
      * TARGET_HAS_HDR_DISPLAY to true in BoardConfig.mk
+     * TARGET_HAS_WIDE_COLOR_DISPLAY must be set to true when
+     * TARGET_HAS_HDR_DISPLAY is true.
      */
     hasHDRDisplay() generates (OptionalBool value);
 
diff --git a/configstore/1.1/default/SurfaceFlingerConfigs.h b/configstore/1.1/default/SurfaceFlingerConfigs.h
deleted file mode 100644
index 3714e81..0000000
--- a/configstore/1.1/default/SurfaceFlingerConfigs.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
-#define ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
-
-#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-namespace android {
-namespace hardware {
-namespace configstore {
-namespace V1_1 {
-namespace implementation {
-
-using ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct SurfaceFlingerConfigs : public ISurfaceFlingerConfigs {
-    // Methods from
-    // ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs follow.
-    Return<void> vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
-    Return<void> vsyncSfEventPhaseOffsetNs(vsyncSfEventPhaseOffsetNs_cb _hidl_cb) override;
-    Return<void> useContextPriority(useContextPriority_cb _hidl_cb) override;
-    Return<void> hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) override;
-    Return<void> hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) override;
-    Return<void> presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) override;
-    Return<void> useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) override;
-    Return<void> maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) override;
-    Return<void> hasSyncFramework(hasSyncFramework_cb _hidl_cb) override;
-    Return<void> useVrFlinger(useVrFlinger_cb _hidl_cb) override;
-    Return<void> maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) override;
-    Return<void> startGraphicsAllocatorService(startGraphicsAllocatorService_cb _hidl_cb) override;
-
-    // Methods from
-    // ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs follow.
-    Return<void> primaryDisplayOrientation(primaryDisplayOrientation_cb _hidl_cb) override;
-
-    // Methods from ::android::hidl::base::V1_0::IBase follow.
-};
-
-}  // namespace implementation
-}  // namespace V1_1
-}  // namespace configstore
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_1_SURFACEFLINGERCONFIGS_H
diff --git a/configstore/1.2/Android.bp b/configstore/1.2/Android.bp
new file mode 100644
index 0000000..a20eb34
--- /dev/null
+++ b/configstore/1.2/Android.bp
@@ -0,0 +1,18 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.configstore@1.2",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "ISurfaceFlingerConfigs.hal",
+    ],
+    interfaces: [
+        "android.hardware.configstore@1.1",
+        "android.hardware.configstore@1.0",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
\ No newline at end of file
diff --git a/configstore/1.2/ISurfaceFlingerConfigs.hal b/configstore/1.2/ISurfaceFlingerConfigs.hal
new file mode 100644
index 0000000..c32cc82
--- /dev/null
+++ b/configstore/1.2/ISurfaceFlingerConfigs.hal
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.configstore@1.2;
+
+import @1.1::ISurfaceFlingerConfigs;
+import @1.0::OptionalBool;
+
+/**
+ * New revision of ISurfaceFlingerConfigs
+ */
+interface ISurfaceFlingerConfigs extends @1.1::ISurfaceFlingerConfigs {
+    /**
+     * useColorManagement indicates whether SurfaceFlinger should manage color
+     * by switching to appropriate color mode automatically depending on the
+     * Dataspace of the surfaces on screen.
+     * This function must return true when hasWideColorDisplay or hasHDRDisplay
+     * return true.
+     */
+    useColorManagement() generates (OptionalBool value);
+};
diff --git a/configstore/1.1/default/Android.mk b/configstore/1.2/default/Android.mk
similarity index 67%
rename from configstore/1.1/default/Android.mk
rename to configstore/1.2/default/Android.mk
index 40f621b..b807357 100644
--- a/configstore/1.1/default/Android.mk
+++ b/configstore/1.2/default/Android.mk
@@ -2,15 +2,15 @@
 
 ################################################################################
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.configstore@1.1-service
+LOCAL_MODULE := android.hardware.configstore@1.2-service
 # seccomp is not required for coverage build.
 ifneq ($(NATIVE_COVERAGE),true)
-LOCAL_REQUIRED_MODULES_arm64 := configstore@1.1.policy
+LOCAL_REQUIRED_MODULES_arm64 := configstore.policy
 endif
-LOCAL_PROPRIETARY_MODULE := true
+LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.configstore@1.1-service.rc
+LOCAL_INIT_RC := android.hardware.configstore@1.2-service.rc
 LOCAL_SRC_FILES:= service.cpp
 
 include $(LOCAL_PATH)/surfaceflinger.mk
@@ -23,16 +23,17 @@
     liblog \
     libutils \
     android.hardware.configstore@1.0 \
-    android.hardware.configstore@1.1
+    android.hardware.configstore@1.1 \
+    android.hardware.configstore@1.2
 
 include $(BUILD_EXECUTABLE)
 
 # seccomp filter for configstore
 ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm64))
 include $(CLEAR_VARS)
-LOCAL_MODULE := configstore@1.1.policy
+LOCAL_MODULE := configstore.policy
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy
-LOCAL_SRC_FILES := seccomp_policy/configstore@1.1-$(TARGET_ARCH).policy
+LOCAL_SRC_FILES := seccomp_policy/configstore-$(TARGET_ARCH).policy
 include $(BUILD_PREBUILT)
 endif
diff --git a/configstore/1.1/default/SurfaceFlingerConfigs.cpp b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
similarity index 90%
rename from configstore/1.1/default/SurfaceFlingerConfigs.cpp
rename to configstore/1.2/default/SurfaceFlingerConfigs.cpp
index da3081c..c7bd567 100644
--- a/configstore/1.1/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.2/default/SurfaceFlingerConfigs.cpp
@@ -22,11 +22,10 @@
 namespace android {
 namespace hardware {
 namespace configstore {
-namespace V1_1 {
+namespace V1_2 {
 namespace implementation {
 
-// Methods from ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs
-// follow.
+// ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs implementation.
 Return<void> SurfaceFlingerConfigs::vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
 #ifdef VSYNC_EVENT_PHASE_OFFSET_NS
     _hidl_cb({true, VSYNC_EVENT_PHASE_OFFSET_NS});
@@ -142,8 +141,7 @@
     return Void();
 }
 
-// Methods from ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs
-// follow.
+// ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs implementation.
 
 #ifdef PRIMARY_DISPLAY_ORIENTATION
 static_assert(PRIMARY_DISPLAY_ORIENTATION == 0 || PRIMARY_DISPLAY_ORIENTATION == 90 ||
@@ -191,10 +189,18 @@
     return Void();
 }
 
-// Methods from ::android::hidl::base::V1_0::IBase follow.
+// ::android::hardware::configstore::V1_2::ISurfaceFlingerConfigs implementation.
+Return<void> SurfaceFlingerConfigs::useColorManagement(useColorManagement_cb _hidl_cb) {
+#if defined(USE_COLOR_MANAGEMENT) || defined(HAS_WIDE_COLOR_DISPLAY) || defined(HAS_HDR_DISPLAY)
+    _hidl_cb({true, true});
+#else
+    _hidl_cb({true, false});
+#endif
+    return Void();
+}
 
 }  // namespace implementation
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace configstore
 }  // namespace hardware
 }  // namespace android
diff --git a/configstore/1.2/default/SurfaceFlingerConfigs.h b/configstore/1.2/default/SurfaceFlingerConfigs.h
new file mode 100644
index 0000000..fe78789
--- /dev/null
+++ b/configstore/1.2/default/SurfaceFlingerConfigs.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CONFIGSTORE_V1_2_SURFACEFLINGERCONFIGS_H
+#define ANDROID_HARDWARE_CONFIGSTORE_V1_2_SURFACEFLINGERCONFIGS_H
+
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace configstore {
+namespace V1_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::configstore::V1_2::ISurfaceFlingerConfigs;
+
+struct SurfaceFlingerConfigs : public ISurfaceFlingerConfigs {
+    // ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs implementation.
+    Return<void> vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) override;
+    Return<void> vsyncSfEventPhaseOffsetNs(vsyncSfEventPhaseOffsetNs_cb _hidl_cb) override;
+    Return<void> useContextPriority(useContextPriority_cb _hidl_cb) override;
+    Return<void> hasWideColorDisplay(hasWideColorDisplay_cb _hidl_cb) override;
+    Return<void> hasHDRDisplay(hasHDRDisplay_cb _hidl_cb) override;
+    Return<void> presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) override;
+    Return<void> useHwcForRGBtoYUV(useHwcForRGBtoYUV_cb _hidl_cb) override;
+    Return<void> maxVirtualDisplaySize(maxVirtualDisplaySize_cb _hidl_cb) override;
+    Return<void> hasSyncFramework(hasSyncFramework_cb _hidl_cb) override;
+    Return<void> useVrFlinger(useVrFlinger_cb _hidl_cb) override;
+    Return<void> maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) override;
+    Return<void> startGraphicsAllocatorService(startGraphicsAllocatorService_cb _hidl_cb) override;
+
+    // ::android::hardware::configstore::V1_1::ISurfaceFlingerConfigs follow implementation.
+    Return<void> primaryDisplayOrientation(primaryDisplayOrientation_cb _hidl_cb) override;
+
+    // ::android::hardware::configstore::V1_2::ISurfaceFlingerConfigs follow implementation.
+    Return<void> useColorManagement(useColorManagement_cb _hidl_cb) override;
+};
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace configstore
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CONFIGSTORE_V1_2_SURFACEFLINGERCONFIGS_H
diff --git a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc b/configstore/1.2/default/android.hardware.configstore@1.2-service.rc
similarity index 83%
rename from configstore/1.1/default/android.hardware.configstore@1.1-service.rc
rename to configstore/1.2/default/android.hardware.configstore@1.2-service.rc
index 105678a..d6c5d10 100644
--- a/configstore/1.1/default/android.hardware.configstore@1.1-service.rc
+++ b/configstore/1.2/default/android.hardware.configstore@1.2-service.rc
@@ -1,4 +1,4 @@
-service vendor.configstore-hal /vendor/bin/hw/android.hardware.configstore@1.1-service
+service vendor.configstore-hal /vendor/bin/hw/android.hardware.configstore@1.2-service
     class hal animation
     user system
     group system
diff --git a/configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy b/configstore/1.2/default/seccomp_policy/configstore-arm64.policy
similarity index 100%
rename from configstore/1.1/default/seccomp_policy/configstore@1.1-arm64.policy
rename to configstore/1.2/default/seccomp_policy/configstore-arm64.policy
diff --git a/configstore/1.1/default/service.cpp b/configstore/1.2/default/service.cpp
similarity index 80%
rename from configstore/1.1/default/service.cpp
rename to configstore/1.2/default/service.cpp
index 3b4e774..65a42f5 100644
--- a/configstore/1.1/default/service.cpp
+++ b/configstore/1.2/default/service.cpp
@@ -14,27 +14,27 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.hardware.configstore@1.1-service"
+#define LOG_TAG "android.hardware.configstore@1.2-service"
 
-#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
 #include <hidl/HidlTransportSupport.h>
 #include <hwminijail/HardwareMinijail.h>
 
 #include "SurfaceFlingerConfigs.h"
 
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
-using android::hardware::configstore::V1_1::ISurfaceFlingerConfigs;
-using android::hardware::configstore::V1_1::implementation::SurfaceFlingerConfigs;
-using android::hardware::SetupMinijail;
+using android::OK;
 using android::sp;
 using android::status_t;
-using android::OK;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::SetupMinijail;
+using android::hardware::configstore::V1_2::ISurfaceFlingerConfigs;
+using android::hardware::configstore::V1_2::implementation::SurfaceFlingerConfigs;
 
 int main() {
     configureRpcThreadpool(10, true);
 
-    SetupMinijail("/vendor/etc/seccomp_policy/configstore@1.1.policy");
+    SetupMinijail("/vendor/etc/seccomp_policy/configstore.policy");
 
     sp<ISurfaceFlingerConfigs> surfaceFlingerConfigs = new SurfaceFlingerConfigs;
     status_t status = surfaceFlingerConfigs->registerAsService();
diff --git a/configstore/1.1/default/surfaceflinger.mk b/configstore/1.2/default/surfaceflinger.mk
similarity index 94%
rename from configstore/1.1/default/surfaceflinger.mk
rename to configstore/1.2/default/surfaceflinger.mk
index 35922eb..70be450 100644
--- a/configstore/1.1/default/surfaceflinger.mk
+++ b/configstore/1.2/default/surfaceflinger.mk
@@ -54,3 +54,7 @@
 ifneq ($(SF_PRIMARY_DISPLAY_ORIENTATION),)
     LOCAL_CFLAGS += -DPRIMARY_DISPLAY_ORIENTATION=$(SF_PRIMARY_DISPLAY_ORIENTATION)
 endif
+
+ifeq ($(TARGET_USE_COLOR_MANAGEMENT),true)
+    LOCAL_CFLAGS += -DUSE_COLOR_MANAGEMENT
+endif
diff --git a/configstore/utils/Android.bp b/configstore/utils/Android.bp
index 178f245..e0d4aa8 100644
--- a/configstore/utils/Android.bp
+++ b/configstore/utils/Android.bp
@@ -30,12 +30,14 @@
     shared_libs: [
         "android.hardware.configstore@1.0",
         "android.hardware.configstore@1.1",
+        "android.hardware.configstore@1.2",
         "libbase",
         "libhidlbase"
     ],
     export_shared_lib_headers: [
         "android.hardware.configstore@1.0",
         "android.hardware.configstore@1.1",
+        "android.hardware.configstore@1.2",
         "libbase",
         "libhidlbase"
     ],
diff --git a/current.txt b/current.txt
index ebfd123..35143af 100644
--- a/current.txt
+++ b/current.txt
@@ -335,7 +335,8 @@
 675682dd3007805c985eaaec91612abc88f4c25b3431fb84070b7584a1a741fb android.hardware.health@2.0::IHealth
 434c4c32c00b0e54bb05e40c79503208b40f786a318029a2a4f66e34f10f2a76 android.hardware.health@2.0::IHealthInfoCallback
 c9e498f1ade5e26f00d290b4763a9671ec6720f915e7d592844b62e8cb1f9b5c android.hardware.health@2.0::types
-6122abe9bc2e7868463d3787db2991c1e47cc01fe3e4cfb7293c5ba421ff8ad9 android.hardware.keymaster@4.0::IKeymasterDevice
+201f9723353fdbd40bf3705537fb7e015e4c399879425e68688fe0f43606ea4d android.hardware.keymaster@4.0::IKeymasterDevice # b/112688384
+6122abe9bc2e7868463d3787db2991c1e47cc01fe3e4cfb7293c5ba421ff8ad9 android.hardware.keymaster@4.0::IKeymasterDevice # b/78104779
 1b7d2090c0a28b229d37c4b96160796b1f0d703950ac6ccc163fccd280830503 android.hardware.keymaster@4.0::types
 6d5c646a83538f0f9d8438c259932509f4353410c6c76e56db0d6ca98b69c3bb android.hardware.media.bufferpool@1.0::IAccessor
 b8c7ed58aa8740361e63d0ce9e7c94227572a629f356958840b34809d2393a7c android.hardware.media.bufferpool@1.0::IClientManager
@@ -385,6 +386,7 @@
 
 # ABI preserving changes to HALs during Android Q
 a95745bbf76aea16a76518bd7efe70cabc5886d09eaeffc993c2e1787a22ed23 android.hardware.camera.metadata@3.3::types
+5f936a5befde7af8d2a683670f80a836b4741e94d84b7b39026da3ed78be9906 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
 574e8f1499436fb4075894dcae0b36682427956ecb114f17f1fe22d116a83c6b android.hardware.neuralnetworks@1.0::IPreparedModel
 1a5ae9793223658174258b523763c557abad6fb917df0b8e3cc097fc89035811 android.hardware.neuralnetworks@1.0::types
 4310eb8272f085914952f3bfb73a8f8bb477a80e8b93596f0ea5acb58546b66d android.hardware.neuralnetworks@1.1::types
diff --git a/graphics/composer/2.1/utils/vts/TestCommandReader.cpp b/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
index 6f8f1ad..e1dc5b6 100644
--- a/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
+++ b/graphics/composer/2.1/utils/vts/TestCommandReader.cpp
@@ -26,23 +26,53 @@
 namespace vts {
 
 void TestCommandReader::parse() {
+    mCompositionChanges.clear();
     while (!isEmpty()) {
         IComposerClient::Command command;
         uint16_t length;
         ASSERT_TRUE(beginCommand(&command, &length));
 
         switch (command) {
+            case IComposerClient::Command::SELECT_DISPLAY:
+                ASSERT_EQ(2, length);
+                read64();  // display
+                break;
             case IComposerClient::Command::SET_ERROR: {
                 ASSERT_EQ(2, length);
                 auto loc = read();
                 auto err = readSigned();
                 GTEST_FAIL() << "unexpected error " << err << " at location " << loc;
             } break;
-            case IComposerClient::Command::SELECT_DISPLAY:
             case IComposerClient::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 IComposerClient::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 IComposerClient::Command::SET_PRESENT_FENCE:
+                ASSERT_EQ(1, length);
+                close(readFence());
+                break;
             case IComposerClient::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
diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
index 3888eeb..b9a4a5c 100644
--- a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/TestCommandReader.h
@@ -32,6 +32,8 @@
     // Parse all commands in the return command queue.  Call GTEST_FAIL() for
     // unexpected errors or commands.
     void parse();
+
+    std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
 };
 
 }  // namespace vts
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index f2596a4..459e0fe 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -138,12 +138,11 @@
 }
 
 void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
-    hidl_handle handle;
     mClient->getReadbackBufferFence(display, [&](const auto& tmpError, const auto& tmpHandle) {
         ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback fence";
-        handle = tmpHandle;
+        const native_handle_t* nativeFenceHandle = tmpHandle.getNativeHandle();
+        *outFence = dup(nativeFenceHandle->data[0]);
     });
-    *outFence = 0;
 }
 
 std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 669fbae..acc9245 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -17,12 +17,15 @@
 cc_test {
     name: "VtsHalGraphicsComposerV2_2TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["VtsHalGraphicsComposerV2_2TargetTest.cpp"],
+    srcs: [
+        "VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
+        "VtsHalGraphicsComposerV2_2TargetTest.cpp",
+    ],
 
     // TODO(b/64437680): Assume these libs are always available on the device.
     shared_libs: [
         "libfmq",
-	"libhidltransport",
+        "libhidltransport",
         "libsync",
     ],
     static_libs: [
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
new file mode 100644
index 0000000..fc32951
--- /dev/null
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#define LOG_TAG "graphics_composer_hidl_hal_readback_tests@2.2"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
+#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
+#include <composer-vts/2.1/GraphicsComposerCallback.h>
+#include <composer-vts/2.1/TestCommandReader.h>
+#include <composer-vts/2.2/ComposerVts.h>
+#include <mapper-vts/2.1/MapperVts.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_2 {
+namespace vts {
+namespace {
+
+using android::hardware::hidl_handle;
+using common::V1_1::BufferUsage;
+using common::V1_1::Dataspace;
+using common::V1_1::PixelFormat;
+using mapper::V2_1::IMapper;
+using mapper::V2_1::vts::Gralloc;
+using V2_1::Display;
+using V2_1::Layer;
+using V2_1::vts::TestCommandReader;
+
+// Test environment for graphics.composer
+class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static GraphicsComposerHidlEnvironment* Instance() {
+        static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
+        return instance;
+    }
+    virtual void registerTestServices() override { registerTestService<IComposer>(); }
+
+   private:
+    GraphicsComposerHidlEnvironment() {}
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
+};
+
+class TestLayer {
+   public:
+    TestLayer(std::shared_ptr<ComposerClient> const client, Display display)
+        : mLayer(client->createLayer(display, kBufferSlotCount)),
+          mComposerClient(client),
+          mDisplay(display) {}
+
+    virtual ~TestLayer() { mComposerClient->destroyLayer(mDisplay, mLayer); }
+
+    virtual void write(std::shared_ptr<CommandWriterBase> writer) {
+        writer->selectLayer(mLayer);
+        writer->setLayerDisplayFrame(mDisplayFrame);
+        writer->setLayerZOrder(mZOrder);
+    }
+
+    void setDisplayFrame(IComposerClient::Rect frame) { mDisplayFrame = frame; }
+    void setZOrder(uint32_t z) { mZOrder = z; }
+
+   protected:
+    Layer mLayer;
+    IComposerClient::Rect mDisplayFrame = {0, 0, 0, 0};
+    uint32_t mZOrder = 0;
+
+   private:
+    std::shared_ptr<ComposerClient> const mComposerClient;
+    const Display mDisplay;
+    static constexpr uint32_t kBufferSlotCount = 64;
+};
+
+class TestColorLayer : public TestLayer {
+   public:
+    TestColorLayer(std::shared_ptr<ComposerClient> const client, Display display)
+        : TestLayer{client, display} {}
+
+    void write(std::shared_ptr<CommandWriterBase> writer) override {
+        TestLayer::write(writer);
+        writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
+        writer->setLayerColor(mColor);
+    }
+
+    void setColor(IComposerClient::Color color) { mColor = color; }
+
+   private:
+    IComposerClient::Color mColor = {0xff, 0xff, 0xff, 0xff};
+};
+
+class GraphicsComposerReadbackTest : public ::testing::VtsHalHidlTargetTestBase {
+   protected:
+    using PowerMode = V2_1::IComposerClient::PowerMode;
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(
+            mComposer = std::make_unique<Composer>(
+                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
+        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
+        mComposerClient->registerCallback(mComposerCallback);
+
+        // assume the first display is primary and is never removed
+        mPrimaryDisplay = waitForFirstDisplay();
+        Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
+        width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                     IComposerClient::Attribute::WIDTH);
+        height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                      IComposerClient::Attribute::HEIGHT);
+
+        // explicitly disable vsync
+        mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
+        mComposerCallback->setVsyncAllowed(false);
+
+        // set up command writer/reader and gralloc
+        mWriter = std::make_shared<CommandWriterBase>(1024);
+        mReader = std::make_unique<TestCommandReader>();
+        mGralloc = std::make_unique<Gralloc>();
+    }
+
+    ~GraphicsComposerReadbackTest() override {
+        if (mComposerCallback != nullptr) {
+            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+        }
+    }
+
+    void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
+
+    void render(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+        for (auto layer : layers) {
+            layer->write(mWriter);
+        }
+        execute();
+        mWriter->validateDisplay();
+        mWriter->presentDisplay();
+        execute();
+    }
+
+    int32_t GetBytesPerPixel(PixelFormat format) {
+        switch (format) {
+            case PixelFormat::RGBA_8888:
+                return 4;
+            case PixelFormat::RGB_888:
+                return 3;
+            default:
+                return -1;
+        }
+    }
+
+    bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
+                           const Error& error) {
+        if (error == Error::UNSUPPORTED) {
+            return false;
+        }
+        // TODO: add support for RGBA_1010102
+        if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
+            return false;
+        }
+        if (dataspace != Dataspace::V0_SRGB) {
+            return false;
+        }
+        return true;
+    }
+
+    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+                                     Dataspace* outDataspace, Error* outError) {
+        mComposerClient->getRaw()->getReadbackBufferAttributes(
+            display,
+            [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
+                *outError = tmpError;
+                *outPixelFormat = tmpOutPixelFormat;
+                *outDataspace = tmpOutDataspace;
+            });
+
+        // Not all devices support readback.  Pass test if this is the case
+        if (!readbackSupported(*outPixelFormat, *outDataspace, *outError)) {
+            GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        }
+    }
+
+    void checkReadbackBuffer(IMapper::BufferDescriptorInfo info, uint32_t stride, void* bufferData,
+                             std::vector<IComposerClient::Color> expectedColors) {
+        int32_t bytesPerPixel = GetBytesPerPixel(info.format);
+        ASSERT_NE(-1, bytesPerPixel)
+            << "unexpected pixel format " << static_cast<int32_t>(info.format)
+            << "(expected RGBA_8888 or RGB_888)";
+        for (int row = 0; row < height; row++) {
+            for (int col = 0; col < width; col++) {
+                int pixel = row * width + col;
+                int offset = (row * stride + col) * bytesPerPixel;
+                uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+
+                EXPECT_EQ(expectedColors[pixel].r, pixelColor[0]);
+                EXPECT_EQ(expectedColors[pixel].g, pixelColor[1]);
+                EXPECT_EQ(expectedColors[pixel].b, pixelColor[2]);
+            }
+        }
+    }
+
+    std::unique_ptr<Composer> mComposer;
+    std::shared_ptr<ComposerClient> mComposerClient;
+
+    sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
+    // the first display and is assumed never to be removed
+    Display mPrimaryDisplay;
+    int32_t width;
+    int32_t height;
+    std::shared_ptr<CommandWriterBase> mWriter;
+    std::unique_ptr<TestCommandReader> mReader;
+    std::unique_ptr<Gralloc> mGralloc;
+
+   private:
+    Display waitForFirstDisplay() {
+        while (true) {
+            std::vector<Display> displays = mComposerCallback->getDisplays();
+            if (displays.empty()) {
+                usleep(5 * 1000);
+                continue;
+            }
+            return displays[0];
+        }
+    }
+};
+
+TEST_F(GraphicsComposerReadbackTest, SingleSolidColorLayer) {
+    mWriter->selectDisplay(mPrimaryDisplay);
+    mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
+    mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::SRGB, RenderIntent::COLORIMETRIC);
+
+    auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+    IComposerClient::Color color({0, 0, 0xff, 0xff});
+    IComposerClient::Rect coloredSquare({100, 100, 500, 500});
+    layer->setColor(color);
+    layer->setDisplayFrame(coloredSquare);
+    layer->setZOrder(10);
+
+    std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+    // expected color for each pixel
+    std::vector<IComposerClient::Color> expectedColors(width * height);
+    for (int row = 0; row < height; row++) {
+        for (int col = 0; col < width; col++) {
+            int pixel = row * width + col;
+            if (row >= coloredSquare.top && row < coloredSquare.bottom &&
+                col >= coloredSquare.left && col < coloredSquare.right) {
+                expectedColors[pixel] = color;
+            } else {
+                expectedColors[pixel] = {0, 0, 0, 0xff};
+            }
+        }
+    }
+
+    PixelFormat pixelFormat;
+    Dataspace dataspace;
+    Error error;
+    getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace, &error);
+
+    IMapper::BufferDescriptorInfo info;
+    info.width = width;
+    info.height = height;
+    info.layerCount = 1;
+    info.format = pixelFormat;
+    info.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
+
+    uint32_t stride;
+    const native_handle_t* buffer = mGralloc->allocate(info, /*import*/ true, &stride);
+    mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
+
+    render(layers);
+
+    int32_t fenceHandle;
+    mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle);
+
+    base::unique_fd fence(fenceHandle);
+
+    // lock buffer
+    // Create Rect accessRegion to specify reading the entire buffer
+    IMapper::Rect accessRegion;
+    accessRegion.left = 0;
+    accessRegion.top = 0;
+    accessRegion.width = info.width;
+    accessRegion.height = info.height;
+
+    void* bufData = mGralloc->lock(buffer, info.usage, accessRegion, fence);
+    checkReadbackBuffer(info, stride, bufData, expectedColors);
+}
+
+}  // anonymous namespace
+}  // namespace vts
+}  // namespace V2_2
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index e3b7f55..e40dc22 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -18,11 +18,11 @@
 
 #include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
-#include <android/hardware/graphics/mapper/2.1/IMapper.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
 #include <composer-vts/2.1/GraphicsComposerCallback.h>
 #include <composer-vts/2.1/TestCommandReader.h>
 #include <composer-vts/2.2/ComposerVts.h>
-#include <mapper-vts/2.1/MapperVts.h>
+#include <mapper-vts/2.0/MapperVts.h>
 
 namespace android {
 namespace hardware {
@@ -39,8 +39,8 @@
 using common::V1_1::Dataspace;
 using common::V1_1::PixelFormat;
 using common::V1_1::RenderIntent;
-using mapper::V2_1::IMapper;
-using mapper::V2_1::vts::Gralloc;
+using mapper::V2_0::IMapper;
+using mapper::V2_0::vts::Gralloc;
 
 // Test environment for graphics.composer
 class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
@@ -134,7 +134,7 @@
         info.width = 64;
         info.height = 64;
         info.layerCount = 1;
-        info.format = PixelFormat::RGBA_8888;
+        info.format = static_cast<common::V1_0::PixelFormat>(PixelFormat::RGBA_8888);
         info.usage =
             static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
 
@@ -278,7 +278,7 @@
     info.height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
                                                        IComposerClient::Attribute::HEIGHT);
     info.layerCount = 1;
-    info.format = pixelFormat;
+    info.format = static_cast<common::V1_0::PixelFormat>(pixelFormat);
     // BufferUsage::COMPOSER_OUTPUT is missing
     info.usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
 
diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp
new file mode 100644
index 0000000..405990e
--- /dev/null
+++ b/media/bufferpool/2.0/Android.bp
@@ -0,0 +1,26 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.media.bufferpool@2.0",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "types.hal",
+        "IAccessor.hal",
+        "IClientManager.hal",
+        "IConnection.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+    ],
+    types: [
+        "Buffer",
+        "BufferStatus",
+        "BufferStatusMessage",
+        "ResultStatus",
+    ],
+    gen_java: false,
+}
+
diff --git a/media/bufferpool/2.0/IAccessor.hal b/media/bufferpool/2.0/IAccessor.hal
new file mode 100644
index 0000000..07ea99d
--- /dev/null
+++ b/media/bufferpool/2.0/IAccessor.hal
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 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.media.bufferpool@2.0;
+
+import IConnection;
+/**
+ * IAccessor creates IConnection which is used from IClientManager in order to
+ * use functionality of the specified buffer pool.
+ */
+interface IAccessor {
+
+    /**
+     * Registers a new client and creates IConnection to the buffer pool for
+     * the client. IConnection and FMQ are used by IClientManager in order to
+     * communicate with the buffer pool. Via FMQ IClientManager sends
+     * BufferStatusMesage(s) to the buffer pool.
+     *
+     * FMQ is used to send buffer ownership status changes to a buffer pool
+     * from a buffer pool client. A buffer pool synchronizes FMQ messages when
+     * there is a hidl request from the clients. Every client has its own
+     * connection and FMQ to communicate with the buffer pool. So sending an
+     * FMQ message on behalf of other clients is not possible.
+     *
+     * FMQ messages are sent when a buffer is acquired or released. Also, FMQ
+     * messages are sent when a buffer is transferred from a client to another
+     * client. FMQ has its own ID from a buffer pool. A client is specified
+     * with the ID.
+     *
+     * To transfer a buffer, a sender must send an FMQ message. The message
+     * must include a receiver's ID and a transaction ID. A receiver must send
+     * the transaction ID to fetch a buffer from a buffer pool. Since the
+     * sender already registered the receiver via an FMQ message, The buffer
+     * pool must verify the receiver with the transaction ID. In order to
+     * prevent faking a receiver, a connection to a buffer pool from client is
+     * made and kept private. Also part of transaction ID is a sender ID in
+     * order to prevent fake transactions from other clients. This must be
+     * verified with an FMQ message from a buffer pool.
+     *
+     * @return status The status of the call.
+     *     OK               - A connection is made successfully.
+     *     NO_MEMORY        - Memory allocation failure occurred.
+     *     ALREADY_EXISTS   - A connection was already made.
+     *     CRITICAL_ERROR   - Other errors.
+     * @return connection The IConnection have interfaces
+     *     to get shared buffers from the buffer pool.
+     * @return connectionId Id of IConnection. The Id identifies
+     *     sender and receiver in FMQ messages during buffer transfer.
+     * @return mqDesc FMQ descriptor. The descriptor can be used to
+     *     send/receive FMQ messages.
+     */
+    connect()
+        generates (ResultStatus status, IConnection connection,
+                   int64_t connectionId, fmq_sync<BufferStatusMessage> mqDesc);
+};
diff --git a/media/bufferpool/2.0/IClientManager.hal b/media/bufferpool/2.0/IClientManager.hal
new file mode 100644
index 0000000..9253bda
--- /dev/null
+++ b/media/bufferpool/2.0/IClientManager.hal
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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.media.bufferpool@2.0;
+
+import IAccessor;
+
+/**
+ * IClientManager manages IConnection(s) inside a process. A locally
+ * created IConnection represents a communication node(receiver) with the
+ * specified buffer pool(IAccessor).
+ * IConnection(s) are not exposed to other processes(IClientManager).
+ * IClientManager instance must be unique within a process.
+ */
+interface IClientManager {
+
+    /**
+     * Sets up a buffer receiving communication node for the specified
+     * buffer pool. A manager must create a IConnection to the buffer
+     * pool if it does not already have a connection.
+     *
+     * @param bufferPool a buffer pool which is specified with the IAccessor.
+     *     The specified buffer pool is the owner of received buffers.
+     * @return status The status of the call.
+     *     OK               - A sender was set successfully.
+     *     NO_MEMORY        - Memory allocation failure occurred.
+     *     ALREADY_EXISTS   - A sender was registered already.
+     *     CRITICAL_ERROR   - Other errors.
+     * @return connectionId the Id of the communication node to the buffer pool.
+     *     This id is used in FMQ to notify IAccessor that a buffer has been
+     *     sent to that connection during transfers.
+     */
+    registerSender(IAccessor bufferPool) generates
+        (ResultStatus status, int64_t connectionId);
+};
diff --git a/media/bufferpool/2.0/IConnection.hal b/media/bufferpool/2.0/IConnection.hal
new file mode 100644
index 0000000..629f83c
--- /dev/null
+++ b/media/bufferpool/2.0/IConnection.hal
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.media.bufferpool@2.0;
+
+/**
+ * A connection to a buffer pool which handles requests from a buffer pool
+ * client. The connection must be made in order to receive buffers from
+ * other buffer pool clients.
+ */
+interface IConnection {
+
+    /**
+     * Retrieves a buffer using bufferId. The method must be called from
+     * receiving side of buffer during transferring only when the specified
+     * buffer is neither cached nor used. This fails if the specified
+     * transaction is not valid.
+     *
+     * @param transactionId Unique transaction id for buffer transferring.
+     * @param bufferId Id of the buffer to be fetched.
+     * @return status The status of the call.
+     *     OK               - A buffer was fetched successfully.
+     *     NO_MEMORY        - Memory allocation failure occurred.
+     *     NOT_FOUND        - A buffer was not found due to invalidation.
+     *     CRITICAL_ERROR   - Other errors.
+     * @return buffer The actual buffer which is specified with bufferId.
+     */
+    fetch(uint64_t transactionId, uint32_t bufferId) generates
+        (ResultStatus status, Buffer buffer);
+};
diff --git a/media/bufferpool/2.0/README.md b/media/bufferpool/2.0/README.md
new file mode 100644
index 0000000..ed985d8
--- /dev/null
+++ b/media/bufferpool/2.0/README.md
@@ -0,0 +1,54 @@
+1. Overview
+
+A buffer pool enables processes to transfer buffers asynchronously.
+Without a buffer pool, a process calls a synchronous method of the other
+process and waits until the call finishes transferring a buffer. This adds
+unwanted latency due to context switching. With help from a buffer pool, a
+process can pass buffers asynchronously and reduce context switching latency.
+
+Passing an interface and a handle adds extra latency also. To mitigate the
+latency, passing IDs with local cache is used. For security concerns about
+rogue clients, FMQ is used to communicate between a buffer pool and a client
+process. FMQ is used to send buffer ownership change status from a client
+process to a buffer pool. Except FMQ, a buffer pool does not use any shared
+memory.
+
+2. FMQ
+
+FMQ is used to send buffer ownership status changes to a buffer pool from a
+buffer pool client. A buffer pool synchronizes FMQ messages when there is a
+hidl request from the clients. Every client has its own connection and FMQ
+to communicate with the buffer pool. So sending an FMQ message on behalf of
+other clients is not possible.
+
+FMQ messages are sent when a buffer is acquired or released. Also, FMQ messages
+are sent when a buffer is transferred from a client to another client. FMQ has
+its own ID from a buffer pool. A client is specified with the ID.
+
+To transfer a buffer, a sender must send an FMQ message. The message must
+include a receiver's ID and a transaction ID. A receiver must send the
+transaction ID to fetch a buffer from a buffer pool. Since the sender already
+registered the receiver via an FMQ message, The buffer pool must verify the
+receiver with the transaction ID. In order to prevent faking a receiver, a
+connection to a buffer pool from client is made and kept privately. Also part of
+transaction ID is a sender ID in order to prevent fake transactions from other
+clients. This must be verified with an FMQ message from a buffer pool.
+
+FMQ messages are defined in BufferStatus and BufferStatusMessage of 'types.hal'.
+
+3. Interfaces
+
+IConnection
+A connection to a buffer pool from a buffer pool client. The connection
+provides the functionalities to share buffers between buffer pool clients.
+The connection must be unique for each client.
+
+IAccessor
+An accessor to a buffer pool which makes a connection to the buffer pool.
+IAccesssor#connect creates an IConnection.
+
+IClientManager
+A manager of buffer pool clients and clients' connections to buffer pools. It
+sets up a process to be a receiver of buffers from a buffer pool. The manager
+is unique in a process.
+
diff --git a/media/bufferpool/2.0/types.hal b/media/bufferpool/2.0/types.hal
new file mode 100644
index 0000000..d5b3937
--- /dev/null
+++ b/media/bufferpool/2.0/types.hal
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 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.media.bufferpool@2.0;
+
+enum ResultStatus : int32_t {
+    OK                  = 0,
+
+    NO_MEMORY           = 1,
+    ALREADY_EXISTS      = 2,
+    NOT_FOUND           = 3,
+    CRITICAL_ERROR      = 4,
+};
+
+/**
+ * Generic buffer for fast recycling for media/stagefright.
+ *
+ * During media pipeline buffer references are created, shared and
+ * destroyed frequently. The underlying buffers are allocated on demand
+ * by a buffer pool, and are recycled to the buffer pool when they are
+ * no longer referenced by the clients.
+ *
+ * E.g. ion or gralloc buffer
+ */
+struct Buffer {
+    uint32_t id;
+    handle buffer;
+};
+
+/**
+ * Buffer ownership status for the specified client.
+ * Buffer transfer status for the specified buffer transafer transaction.
+ * BufferStatus is posted along with BufferStatusMessage from a client to
+ * the buffer pool for synchronization after status change.
+ */
+enum BufferStatus : int32_t {
+    /** No longer used by the specified client. */
+    NOT_USED            = 0,
+    /** Buffer is acquired by the specified client. */
+    USED                = 1,
+    /** Buffer is sent by the specified client. */
+    TRANSFER_TO         = 2,
+    /** Buffer transfer is acked by the receiver client. */
+    TRANSFER_FROM       = 3,
+    /** Buffer transfer is timed out by receiver client. */
+    TRANSFER_TIMEOUT    = 4,
+    /** Buffer transfer is not acked by the receiver. */
+    TRANSFER_LOST       = 5,
+    /** Buffer fetch request from the client. */
+    TRANSFER_FETCH      = 6,
+    /** Buffer transaction succeeded. */
+    TRANSFER_OK         = 7,
+    /** Buffer transaction failure. */
+    TRANSFER_ERROR      = 8,
+};
+
+/**
+ * Buffer ownership status change message. This message is
+ * sent via fmq to the buffer pool from client processes.
+ */
+struct BufferStatusMessage {
+    /**
+     * Transaction Id = (SenderId : sender local transaction Id)
+     * Transaction Id is created from sender and posted via fmq within
+     * TRANSFER_TO message.
+     */
+    uint64_t transactionId;
+    uint32_t bufferId;
+    BufferStatus newStatus;
+    /** Used by the buffer pool. not by client. */
+    int64_t connectionId;
+    /** Valid only when TRANSFER_TO is posted. */
+    int64_t targetConnectionId;
+    /**
+     * Used by the buffer pool, not by client.
+     * Monotonic timestamp in Us since fixed point in time as decided
+     * by the sender of the message
+     */
+    int64_t timestampUs;
+};