Merge "Update VHAL types.hal" into pi-dev
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h
index c03b055..8774be9 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h
@@ -451,8 +451,21 @@
 }
 
 #ifdef AUDIO_HAL_VERSION_4_0
-Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& /*sinkMetadata*/) {
-    return Void();  // TODO: propagate to legacy
+Return<void> StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    if (mStream->update_sink_metadata == nullptr) {
+        return Void();  // not supported by the HAL
+    }
+    std::vector<record_track_metadata> halTracks;
+    halTracks.reserve(sinkMetadata.tracks.size());
+    for (auto& metadata : sinkMetadata.tracks) {
+        halTracks.push_back(
+            {.source = static_cast<audio_source_t>(metadata.source), .gain = metadata.gain});
+    }
+    const sink_metadata_t halMetadata = {
+        .track_count = halTracks.size(), .tracks = halTracks.data(),
+    };
+    mStream->update_sink_metadata(mStream, &halMetadata);
+    return Void();
 }
 
 Return<void> StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) {
diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h
index 605b824..77098a8 100644
--- a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h
+++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h
@@ -547,8 +547,24 @@
 }
 
 #ifdef AUDIO_HAL_VERSION_4_0
-Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& /*sourceMetadata*/) {
-    return Void();  // TODO: propagate to legacy
+Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    if (mStream->update_source_metadata == nullptr) {
+        return Void();  // not supported by the HAL
+    }
+    std::vector<playback_track_metadata> halTracks;
+    halTracks.reserve(sourceMetadata.tracks.size());
+    for (auto& metadata : sourceMetadata.tracks) {
+        halTracks.push_back({
+            .usage = static_cast<audio_usage_t>(metadata.usage),
+            .content_type = static_cast<audio_content_type_t>(metadata.contentType),
+            .gain = metadata.gain,
+        });
+    }
+    const source_metadata_t halMetadata = {
+        .track_count = halTracks.size(), .tracks = halTracks.data(),
+    };
+    mStream->update_source_metadata(mStream, &halMetadata);
+    return Void();
 }
 Return<Result> StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) {
     return Result::NOT_SUPPORTED;  // TODO: propagate to legacy
diff --git a/broadcastradio/2.0/ITunerCallback.hal b/broadcastradio/2.0/ITunerCallback.hal
index ede8350..b20a0b2 100644
--- a/broadcastradio/2.0/ITunerCallback.hal
+++ b/broadcastradio/2.0/ITunerCallback.hal
@@ -17,12 +17,14 @@
 
 interface ITunerCallback {
     /**
-     * Method called by the HAL when a tuning operation fails
+     * Method called by the HAL when a tuning operation fails asynchronously
      * following a step(), scan() or tune() command.
      *
-     * @param result OK if tune succeeded;
-     *               TIMEOUT in case of time out.
-     * @param selector A ProgramSelector structure passed from tune(),
+     * This callback is only called when the step(), scan() or tune() command
+     * returned OK at first.
+     *
+     * @param result TIMEOUT in case of time out.
+     * @param selector A ProgramSelector structure passed from tune() call;
      *                 empty for step() and scan().
      */
     oneway onTuneFailed(Result result, ProgramSelector selector);
diff --git a/broadcastradio/2.0/types.hal b/broadcastradio/2.0/types.hal
index a9b9600..1ce61df 100644
--- a/broadcastradio/2.0/types.hal
+++ b/broadcastradio/2.0/types.hal
@@ -351,10 +351,16 @@
      * related content (i.e. DAB soft-links). This field is a list of pointers
      * to other programs on the program list.
      *
-     * Please note, that these identifiers does not have to exist on the program
+     * This is not a list of programs that carry the same content (i.e.
+     * DAB hard-links, RDS AF). Switching to programs from this list usually
+     * require user action.
+     *
+     * Please note, that these identifiers do not have to exist on the program
      * list - i.e. DAB tuner may provide information on FM RDS alternatives
      * despite not supporting FM RDS. If the system has multiple tuners, another
      * one may have it on its list.
+     *
+     * This field is optional (can be empty).
      */
     vec<ProgramIdentifier> relatedContent;
 
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index ad7f6f5..550d65a 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -51,6 +51,32 @@
             }
         }
     }
+
+    camera_metadata_entry_t capabilities =
+            mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    bool isLogicalMultiCamera = false;
+    for (size_t i = 0; i < capabilities.count; i++) {
+        if (capabilities.data.u8[i] ==
+                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+            isLogicalMultiCamera = true;
+            break;
+        }
+    }
+    if (isLogicalMultiCamera) {
+        camera_metadata_entry entry =
+                mDeviceInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
+        const uint8_t* ids = entry.data.u8;
+        size_t start = 0;
+        for (size_t i = 0; i < entry.count; ++i) {
+            if (ids[i] == '\0') {
+                if (start != i) {
+                    const char* physicalId = reinterpret_cast<const char*>(ids+start);
+                    mPhysicalCameraIds.emplace(physicalId);
+                }
+                start = i + 1;
+            }
+        }
+    }
 }
 
 CameraDeviceSession::~CameraDeviceSession() {
@@ -456,9 +482,19 @@
         return;
     }
 
+    if (hal_result->num_physcam_metadata > d->mPhysicalCameraIds.size()) {
+        ALOGE("%s: Fatal: Invalid num_physcam_metadata %u", __FUNCTION__,
+                hal_result->num_physcam_metadata);
+        return;
+    }
     result.physicalCameraMetadata.resize(hal_result->num_physcam_metadata);
     for (uint32_t i = 0; i < hal_result->num_physcam_metadata; i++) {
         std::string physicalId = hal_result->physcam_ids[i];
+        if (d->mPhysicalCameraIds.find(physicalId) == d->mPhysicalCameraIds.end()) {
+            ALOGE("%s: Fatal: Invalid physcam_ids[%u]: %s", __FUNCTION__,
+                  i, hal_result->physcam_ids[i]);
+            return;
+        }
         V3_2::CameraMetadata physicalMetadata;
         V3_2::implementation::convertToHidl(hal_result->physcam_metadata[i], &physicalMetadata);
         PhysicalCameraMetadata physicalCameraMetadata = {
diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
index 6e90ed4..5d6a112 100644
--- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
+++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
@@ -27,6 +27,7 @@
 #include <hidl/Status.h>
 #include <deque>
 #include <map>
+#include <unordered_set>
 #include <unordered_map>
 #include "CameraMetadata.h"
 #include "HandleImporter.h"
@@ -110,6 +111,10 @@
 
     // Whether this camera device session is created with version 3.4 callback.
     bool mHasCallback_3_4;
+
+    // Physical camera ids for the logical multi-camera. Empty if this
+    // is not a logical multi-camera.
+    std::unordered_set<std::string> mPhysicalCameraIds;
 private:
 
     struct TrampolineSessionInterface_3_4 : public ICameraDeviceSession {
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 467e11e..6aa5fc5 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -24,6 +24,14 @@
         </interface>
     </hal>
     <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <version>1.0</version>
+        <interface>
+            <name>IAudioControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
         <name>android.hardware.automotive.evs</name>
         <version>1.0</version>
         <interface>
@@ -104,6 +112,14 @@
         </interface>
     </hal>
     <hal format="hidl" optional="true">
+        <name>android.hardware.confirmationui</name>
+        <version>1.0</version>
+        <interface>
+            <name>IConfirmationUI</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
         <name>android.hardware.contexthub</name>
         <version>1.0</version>
         <interface>
@@ -287,6 +303,14 @@
         </interface>
     </hal>
     <hal format="hidl" optional="true">
+        <name>android.hardware.radio.config</name>
+        <version>1.0</version>
+        <interface>
+            <name>IRadioConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
         <name>android.hardware.renderscript</name>
         <version>1.0</version>
         <interface>
diff --git a/current.txt b/current.txt
index 273455b..eb6401e 100644
--- a/current.txt
+++ b/current.txt
@@ -250,6 +250,8 @@
 c8bc853546dd55584611def2a9fa1d99f657e3366c976d2f60fe6b8aa6d2cb87 android.hardware.thermal@1.1::IThermalCallback
 
 # ABI preserving changes to HALs during Android P
+eaeb3e4f3237430a7fdc206bffdf844713f5682990b2d49ea24392e15b5d343f android.hardware.broadcastradio@2.0::ITunerCallback
+2804120c1f8522ad15feb7695fe5eece527d399b406c671ea99618194118c316 android.hardware.broadcastradio@2.0::types
 cf72ff5a52bfa4d08e9e1000cf3ab5952a2d280c7f13cdad5ab7905c08050766 android.hardware.camera.metadata@3.2::types
 3902efc42097cba55f0655aa389e052ea70164e99ced1a6d1ef53dafc13f7650 android.hardware.camera.provider@2.4::ICameraProvider
 6fa9804a17a8bb7923a56bd10493a5483c20007e4c9026fd04287bee7c945a8c android.hardware.gnss@1.0::IGnssCallback
@@ -316,14 +318,14 @@
 7877ff8e4c1e48b825e6e5e66d050288e5656ed535c61cc7830a92ed4a9e1990 android.hardware.drm@1.1::IDrmFactory
 fef2f0ebde7704548fb203df46673ceb342272fc4fa9d0af25a980d2584a36e7 android.hardware.drm@1.1::IDrmPlugin
 5047a346ecce239404b9020959f60dd467318e9c17b290a6386bc3894df62c3c android.hardware.drm@1.1::types
-be794f5df97f134d6dcabb866b250d1305100e7ae07fb253b7841df890b931bb android.hardware.gnss@1.1::IGnss
+a830336ac8627d6432cfafb1b884343ad9f885dee0a5323e380e6d3c519156b8 android.hardware.gnss@1.1::IGnss
 8ad55bc35bb3a83e65c018bdfde7ae5ebc749ff2bf6b79412ded0bc6c89b97d8 android.hardware.gnss@1.1::IGnssCallback
 3c5183d7506010be57e0f748e3640fc2ded1ba955784b6256ba427f4c399591c android.hardware.gnss@1.1::IGnssConfiguration
-b054af24fbb70d54cde1fb5cba126809e7c4e863e8f9115dc492321dfbcbc993 android.hardware.gnss@1.1::IGnssMeasurement
+1a07d1383e847c3deb696ec7a2c9e33b9683772945660448a010b18063da67a4 android.hardware.gnss@1.1::IGnssMeasurement
 83e7a10ff3702147bd7ffa04567b20d407a3b16bbb7705644af44d919afe9103 android.hardware.gnss@1.1::IGnssMeasurementCallback
-82da7e7624f72ff1927f48738913e20bee3a513adfe5dc7c4f888176e20376e6 android.hardware.graphics.common@1.1::types
+0b96e0254e2168cfecb30c1ed5fb42681652cc00faa68c6e07568fafe64d1d50 android.hardware.graphics.common@1.1::types
 d9b40a5b09962a5a0780b10fe33a4e607e69e2e088fc83de88a584115b7cb1c0 android.hardware.graphics.composer@2.2::IComposer
-d6ce042995239712bc1d0970fa9d512c15c0b1ac9bcb048bd8b69f617b45c25e android.hardware.graphics.composer@2.2::IComposerClient
+c3cd2a3e245ffefae859c9a3d31382a9421be95cfa6bc1231571eb3533049b54 android.hardware.graphics.composer@2.2::IComposerClient
 dd83be076b6b3f10ed62ab34d8c8b95f2415961fb785200eb842e7bfb2b0ee92 android.hardware.graphics.mapper@2.1::IMapper
 675682dd3007805c985eaaec91612abc88f4c25b3431fb84070b7584a1a741fb android.hardware.health@2.0::IHealth
 434c4c32c00b0e54bb05e40c79503208b40f786a318029a2a4f66e34f10f2a76 android.hardware.health@2.0::IHealthInfoCallback
@@ -343,9 +345,9 @@
 7899b9305587b2d5cd74a3cc87e9090f58bf4ae74256ce3ee36e7ec011822840 android.hardware.power@1.2::types
 ab132c990a62f0aca35871c092c22fb9c85d478e22124ef6a4d0a2302da76a9f android.hardware.radio@1.2::IRadio
 cda752aeabaabc20486a82ac57a3dd107785c006094a349bc5e224e8aa22a17c android.hardware.radio@1.2::IRadioIndication
-c38b7e1f808565a535ff19fd4c1b512b22dfa0b58ec91dce03f72a8f1eaf6957 android.hardware.radio@1.2::IRadioResponse
+da8c6ae991c6a4b284cc6e445332e064e28ee8a09482ed5afff9d159ec6694b7 android.hardware.radio@1.2::IRadioResponse
 b65332996eb39ba63300a1011404141fa59ce5c252bc17afae637be6eeca5f55 android.hardware.radio@1.2::ISap
-508ace7d4023b865b8b77c3ca3c86cc9525ef3803dc9c6b461b7c1f91b0fec00 android.hardware.radio@1.2::types
+a9361522cc97ef66209d39ba324095b2f08344054bb4d3481e803eee0480623a android.hardware.radio@1.2::types
 87385469cf4409f0f33b01508e7a477cf71f2a11e466dd7e3ab5971a1baaa72b android.hardware.radio.config@1.0::IRadioConfig
 228b2ee3c8c276c9f0afad2dc313ca3d6bbd9e482ddf313c7204c60ad9b636ab android.hardware.radio.config@1.0::IRadioConfigIndication
 a2e9b7aa09f79426f765838174e04b6f9a3e6c8b76b923fc1705632207bad44b android.hardware.radio.config@1.0::IRadioConfigResponse
@@ -365,7 +367,7 @@
 167af870fdb87e1cbbaa0fa62ef35e1031caad20dd1ba695983dedb1e9993486 android.hardware.wifi@1.2::IWifiChipEventCallback
 8c7ef32fc78d5ec6e6956de3784cc2c6f42614b5272d2e461f6d60534ba38ec2 android.hardware.wifi@1.2::IWifiNanIface
 1e6074efad9da333803fb7c1acdb719d51c30b2e1e92087b0420341631c30b60 android.hardware.wifi@1.2::IWifiNanIfaceEventCallback
-a9d733eb0d555f2a6cb79a212810e81b56ecba0e31a8ffe0916de086a29e4f88 android.hardware.wifi@1.2::IWifiStaIface
+f5682dbf19f712bef9cc3faa5fe3dc670b6ffbcb62a147a1d86b9d43574cd83f android.hardware.wifi@1.2::IWifiStaIface
 6db2e7d274be2dca9bf3087afd1f774a68c99d2b4dc7eeaf41690e5cebcbef7a android.hardware.wifi@1.2::types
 ee08280de21cb41e3ec26d6ed636c701b7f70516e71fb22f4fe60a13e603f406 android.hardware.wifi.hostapd@1.0::IHostapd
 b2479cd7a417a1cf4f3a22db4e4579e21bac38fdcaf381e2bf10176d05397e01 android.hardware.wifi.hostapd@1.0::types
diff --git a/gnss/1.1/IGnss.hal b/gnss/1.1/IGnss.hal
index 096f251..672f742 100644
--- a/gnss/1.1/IGnss.hal
+++ b/gnss/1.1/IGnss.hal
@@ -46,15 +46,17 @@
      * @param minIntervalMs Represents the time between fixes in milliseconds.
      * @param preferredAccuracyMeters Represents the requested fix accuracy in meters.
      * @param preferredTimeMs Represents the requested time to first fix in milliseconds.
-     * @param lowPowerMode When true, HAL must make strong tradeoffs to substantially restrict power
-     *     use. Specifically, in the case of a several second long minIntervalMs, the GNSS chipset
-     *     must not, on average, run power hungry operations like RF and signal searches for more
-     *     than one second per interval, and must make exactly one call to gnssSvStatusCb(), and
-     *     either zero or one call to GnssLocationCb() at each interval. When false, HAL must
-     *     operate in the nominal mode (similar to V1.0 where this flag wasn't present) and is
-     *     expected to make power and performance tradoffs such as duty-cycling when signal
-     *     conditions are good and more active searches to reacquire GNSS signals when no signals
-     *     are present.
+     * @param lowPowerMode When true, and IGnss.hal is the only client to the GNSS hardware, the
+     *     GNSS hardware must make strong tradeoffs to substantially restrict power use.
+     *     Specifically, in the case of a several second long minIntervalMs, the GNSS hardware must
+     *     not, on average, run power hungry operations like RF and signal searches for more than
+     *     one second per interval, and must make exactly one call to gnssSvStatusCb(), and either
+     *     zero or one call to GnssLocationCb() at each interval. When false, HAL must operate in
+     *     the nominal mode (similar to V1.0 where this flag wasn't present) and is expected to make
+     *     power and performance tradoffs such as duty-cycling when signal conditions are good and
+     *     more active searches to reacquire GNSS signals when no signals are present.
+     *     When there are additional clients using the GNSS hardware other than IGnss.hal, the GNSS
+     *     hardware may operate in a higher power mode, on behalf of those clients.
      *
      * @return success Returns true if successful.
      */
diff --git a/gnss/1.1/IGnssMeasurement.hal b/gnss/1.1/IGnssMeasurement.hal
index cd83ae3..6ed8e53 100644
--- a/gnss/1.1/IGnssMeasurement.hal
+++ b/gnss/1.1/IGnssMeasurement.hal
@@ -33,10 +33,11 @@
      * @param callback Handle to GnssMeasurement callback interface.
      * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
      *     no clock discontinuities are expected and, when supported, carrier phase should be
-     *     continuous in good signal conditions. All constellations and frequency bands that the
-     *     chipset supports must be reported in this mode. The GNSS chipset is allowed to consume
-     *     more power in this mode. If false, API must behave as in HAL V1_0, optimizing power via
-     *     duty cycling, constellations and frequency limits, etc.
+     *     continuous in good signal conditions. All non-blacklisted, healthy constellations,
+     *     satellites and frequency bands that the chipset supports must be reported in this mode.
+     *     The GNSS chipset is allowed to consume more power in this mode. If false, API must behave
+     *     as in HAL V1_0, optimizing power via duty cycling, constellations and frequency limits,
+     *     etc.
      *
      * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
      *     already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp
index c319d80..8bc68f5 100644
--- a/graphics/common/1.1/Android.bp
+++ b/graphics/common/1.1/Android.bp
@@ -15,8 +15,10 @@
     ],
     types: [
         "BufferUsage",
+        "ColorMode",
         "Dataspace",
         "PixelFormat",
+        "RenderIntent",
     ],
     gen_java: true,
     gen_java_constants: true,
diff --git a/graphics/common/1.1/types.hal b/graphics/common/1.1/types.hal
index b917d5e..5dca482 100644
--- a/graphics/common/1.1/types.hal
+++ b/graphics/common/1.1/types.hal
@@ -16,9 +16,10 @@
 
 package android.hardware.graphics.common@1.1;
 
-import @1.0::PixelFormat;
 import @1.0::BufferUsage;
+import @1.0::ColorMode;
 import @1.0::Dataspace;
+import @1.0::PixelFormat;
 
 /**
  * Pixel formats for graphics buffers.
@@ -129,15 +130,165 @@
 @export(name="android_dataspace_v1_1_t", value_prefix="HAL_DATASPACE_",
         export_parent="false")
 enum Dataspace : @1.0::Dataspace {
+    /*
+     * @1.0::Dataspace defines six legacy dataspaces
+     *
+     *   SRGB_LINEAR = 0x200, // deprecated, use V0_SRGB_LINEAR
+     *   SRGB = 0x201, // deprecated, use V0_SRGB
+     *   JFIF = 0x101, // deprecated, use V0_JFIF
+     *   BT601_625 = 0x102, // deprecated, use V0_BT601_625
+     *   BT601_525 = 0x103, // deprecated, use V0_BT601_525
+     *   BT709 = 0x104, // deprecated, use V0_BT709
+     *
+     * The difference between the legacy dataspaces and their modern
+     * counterparts is that, with legacy dataspaces, the pixel values may have
+     * been desaturated by the content creator in an unspecified way.
+     *
+     * When colorimetric mapping is required, the legacy dataspaces must be
+     * treated as their modern counterparts (e.g., SRGB must be treated as
+     * V0_SRGB) and no re-saturation is allowed. When non-colorimetric mapping
+     * is allowed, the pixel values can be interpreted freely by
+     * implementations for the purpose of re-saturation, and the re-saturated
+     * pixel values are in the respective modern dataspaces.
+     *
+     * This is also true when UNKNOWN is treated as a legacy dataspace.
+     */
+
     /**
      * ITU-R Recommendation 2020 (BT.2020)
      *
      * Ultra High-definition television
      *
-     * Use limited range, SMPTE 2084 (PQ) transfer and BT2020 standard
-     * limited range is the preferred / normative definition for BT.2020
+     * Use limited range, BT.709 transfer and BT2020 standard
      */
     BT2020_ITU = STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED,
 
+    /**
+     * ITU-R Recommendation 2100 (BT.2100)
+     *
+     * High dynamic range television
+     *
+     * Use limited/full range, PQ/HLG transfer, and BT2020 standard
+     * limited range is the preferred / normative definition for BT.2100
+     */
     BT2020_ITU_PQ = STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED,
+    BT2020_ITU_HLG = STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED,
+    BT2020_HLG = STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL,
+};
+
+@export(name="android_color_mode_v1_1_t", value_prefix="HAL_COLOR_MODE_",
+        export_parent="false")
+enum ColorMode : @1.0::ColorMode {
+    /**
+     * BT2020 corresponds with display settings that implement the ITU-R
+     * Recommendation BT.2020 / Rec. 2020 for UHDTV.
+     *
+     * Primaries:
+     *                  x       y
+     *  green           0.170   0.797
+     *  blue            0.131   0.046
+     *  red             0.708   0.292
+     *  white (D65)     0.3127  0.3290
+     *
+     * Inverse Gamma Correction (IGC): V represents normalized (with [0 to 1]
+     * range) value of R, G, or B.
+     *
+     *  if Vnonlinear < b * 4.5
+     *    Vlinear = Vnonlinear / 4.5
+     *  else
+     *    Vlinear = ((Vnonlinear + (a - 1)) / a) ^ (1/0.45)
+     *
+     * Gamma Correction (GC):
+     *
+     *  if Vlinear < b
+     *    Vnonlinear = 4.5 * Vlinear
+     *  else
+     *    Vnonlinear = a * Vlinear ^ 0.45 - (a - 1)
+     *
+     * where
+     *
+     *   a = 1.09929682680944, b = 0.018053968510807
+     *
+     * For practical purposes, these a/b values can be used instead
+     *
+     *   a = 1.099, b = 0.018 for 10-bit display systems
+     *   a = 1.0993, b = 0.0181 for 12-bit display systems
+     */
+    BT2020 = 10,
+
+    /**
+     * BT2100_PQ and BT2100_HLG correspond with display settings that
+     * implement the ITU-R Recommendation BT.2100 / Rec. 2100 for HDR TV.
+     *
+     * Primaries:
+     *                  x       y
+     *  green           0.170   0.797
+     *  blue            0.131   0.046
+     *  red             0.708   0.292
+     *  white (D65)     0.3127  0.3290
+     *
+     * For BT2100_PQ, the transfer function is Perceptual Quantizer (PQ). For
+     * BT2100_HLG, the transfer function is Hybrid Log-Gamma (HLG).
+     */
+    BT2100_PQ = 11,
+    BT2100_HLG = 12,
+};
+
+/**
+ * RenderIntent defines the mapping from color mode colors to display colors.
+ *
+ * A render intent must not change how it maps colors when the color mode
+ * changes. That is to say that when a render intent maps color C to color C',
+ * the fact that color C can have different pixel values in different color
+ * modes should not affect the mapping.
+ *
+ * RenderIntent overrides the render intents defined for individual color
+ * modes. It is ignored when the color mode is ColorMode::NATIVE, because
+ * ColorMode::NATIVE colors are already display colors.
+ */
+@export(name="android_render_intent_v1_1_t", value_prefix="HAL_RENDER_INTENT_",
+        export_parent="false")
+enum RenderIntent : int32_t {
+    /**
+     * Colors in the display gamut are unchanged. Colors out of the display
+     * gamut are hard-clipped.
+     *
+     * This implies that the display must have been calibrated unless
+     * ColorMode::NATIVE is the only supported color mode.
+     */
+    COLORIMETRIC = 0,
+
+    /**
+     * Enhance colors that are in the display gamut. Colors out of the display
+     * gamut are hard-clipped.
+     *
+     * The enhancement typically picks the biggest standard color space (e.g.
+     * DCI-P3) that is narrower than the display gamut and stretches it to the
+     * display gamut. The stretching is recommended to preserve skin tones.
+     */
+    ENHANCE = 1,
+
+    /**
+     * Tone map high-dynamic-range colors to the display's dynamic range. The
+     * dynamic range of the colors are communicated separately. After tone
+     * mapping, the mapping to the display gamut is as defined in
+     * COLORIMETRIC.
+     */
+    TONE_MAP_COLORIMETRIC = 2,
+
+    /**
+     * Tone map high-dynamic-range colors to the display's dynamic range. The
+     * dynamic range of the colors are communicated separately. After tone
+     * mapping, the mapping to the display gamut is as defined in ENHANCE.
+     *
+     * The tone mapping step and the enhancing step must match
+     * TONE_MAP_COLORIMETRIC and ENHANCE respectively when they are also
+     * supported.
+     */
+    TONE_MAP_ENHANCE = 3,
+
+    /*
+     * Vendors are recommended to use 0x100 - 0x1FF for their own values, and
+     * that must be done with subtypes defined by vendor extensions.
+     */
 };
diff --git a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
index df529ec..2742207 100644
--- a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
+++ b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
@@ -247,21 +247,8 @@
 
     void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
                          Dataspace dataspace, const std::vector<IComposerClient::Rect>& damage) {
-        bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
-        size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
-
-        beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length);
-        write(slot);
-        writeHandle(target, true);
-        writeFence(acquireFence);
-        writeSigned(static_cast<int32_t>(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();
+        setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
+                                damage);
     }
 
     static constexpr uint16_t kSetOutputBufferLength = 3;
@@ -354,9 +341,7 @@
 
     static constexpr uint16_t kSetLayerDataspaceLength = 1;
     void setLayerDataspace(Dataspace dataspace) {
-        beginCommand(IComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
-        writeSigned(static_cast<int32_t>(dataspace));
-        endCommand();
+        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
     }
 
     static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
@@ -418,6 +403,32 @@
     }
 
    protected:
+    void setClientTargetInternal(uint32_t slot, const native_handle_t* target, int acquireFence,
+                                 int32_t dataspace,
+                                 const std::vector<IComposerClient::Rect>& damage) {
+        bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
+        size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
+
+        beginCommand(IComposerClient::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(IComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
+        writeSigned(dataspace);
+        endCommand();
+    }
+
     void beginCommand(IComposerClient::Command command, uint16_t length) {
         if (mCommandEnd) {
             LOG_FATAL("endCommand was not called before command 0x%x", command);
diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
index 0d883e4..8d5493e 100644
--- a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
@@ -104,9 +104,7 @@
 
     void execute(TestCommandReader* reader, CommandWriterBase* writer);
 
-   private:
-    sp<IComposerClient> mClient;
-
+   protected:
     // Keep track of all virtual displays and layers.  When a test fails with
     // ASSERT_*, the destructor will clean up the resources for the test.
     struct DisplayResource {
@@ -116,6 +114,9 @@
         std::unordered_set<Layer> layers;
     };
     std::unordered_map<Display, DisplayResource> mDisplayResources;
+
+   private:
+    sp<IComposerClient> mClient;
 };
 
 }  // namespace vts
diff --git a/graphics/composer/2.2/Android.bp b/graphics/composer/2.2/Android.bp
index 633a208..fe71e9e 100644
--- a/graphics/composer/2.2/Android.bp
+++ b/graphics/composer/2.2/Android.bp
@@ -12,6 +12,7 @@
     ],
     interfaces: [
         "android.hardware.graphics.common@1.0",
+        "android.hardware.graphics.common@1.1",
         "android.hardware.graphics.composer@2.1",
         "android.hidl.base@1.0",
     ],
diff --git a/graphics/composer/2.2/IComposerClient.hal b/graphics/composer/2.2/IComposerClient.hal
index dcd9c8d..b7ba6a6 100644
--- a/graphics/composer/2.2/IComposerClient.hal
+++ b/graphics/composer/2.2/IComposerClient.hal
@@ -16,11 +16,14 @@
 
 package android.hardware.graphics.composer@2.2;
 
-import android.hardware.graphics.common@1.0::PixelFormat;
-import android.hardware.graphics.common@1.0::Dataspace;
+import android.hardware.graphics.common@1.1::ColorMode;
+import android.hardware.graphics.common@1.1::Dataspace;
+import android.hardware.graphics.common@1.1::PixelFormat;
+import android.hardware.graphics.common@1.1::RenderIntent;
 import @2.1::IComposerClient;
 import @2.1::Display;
 import @2.1::Error;
+import @2.1::IComposerClient;
 
 interface IComposerClient extends @2.1::IComposerClient {
 
@@ -90,16 +93,20 @@
 
     enum Command : @2.1::IComposerClient.Command {
         /**
-         * setPerFrameMetadata(Display display, vec<PerFrameMetadata> data)
+         * SET_LAYER_PER_FRAME_METADATA has this pseudo prototype
+         *
+         *   setLayerPerFrameMetadata(Display display, Layer layer,
+         *                            vec<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_PER_FRAME_METADATA is the command used by the buffered transport
+         * SET_LAYER_PER_FRAME_METADATA is the command used by the buffered transport
          * mechanism.
          */
-        SET_PER_FRAME_METADATA = 0x207 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
+        SET_LAYER_PER_FRAME_METADATA = 0x303 << @2.1::IComposerClient.Command:OPCODE_SHIFT,
 
         /**
          * SET_LAYER_COLOR has this pseudo prototype
@@ -242,6 +249,65 @@
     setReadbackBuffer(Display display, handle buffer, handle releaseFence) generates (Error error);
 
     /**
+     * createVirtualDisplay_2_2
+     * Creates a new virtual display with the given width and height. The
+     * format passed into this function is the default format requested by the
+     * consumer of the virtual display output buffers.
+     *
+     * The display must be assumed to be on from the time the first frame is
+     * presented until the display is destroyed.
+     *
+     * @param width is the width in pixels.
+     * @param height is the height in pixels.
+     * @param formatHint is the default output buffer format selected by
+     *        the consumer.
+     * @param outputBufferSlotCount is the number of output buffer slots to be
+     *        reserved.
+     * @return error is NONE upon success. Otherwise,
+     *         UNSUPPORTED when the width or height is too large for the
+     *                     device to be able to create a virtual display.
+     *         NO_RESOURCES when the device is unable to create a new virtual
+     *                      display at this time.
+     * @return display is the newly-created virtual display.
+     * @return format is the format of the buffer the device will produce.
+     */
+    @callflow(next="*")
+    createVirtualDisplay_2_2(uint32_t width,
+                             uint32_t height,
+                             PixelFormat formatHint,
+                             uint32_t outputBufferSlotCount)
+                  generates (Error error,
+                             Display display,
+                             PixelFormat format);
+
+    /**
+     * getClientTargetSupport_2_2
+     * Returns whether a client target with the given properties can be
+     * handled by the device.
+     *
+     * This function must return true for a client target with width and
+     * height equal to the active display configuration dimensions,
+     * PixelFormat::RGBA_8888, and Dataspace::UNKNOWN. It is not required to
+     * return true for any other configuration.
+     *
+     * @param display is the display to query.
+     * @param width is the client target width in pixels.
+     * @param height is the client target height in pixels.
+     * @param format is the client target format.
+     * @param dataspace is the client target dataspace, as described in
+     *        setLayerDataspace.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY when an invalid display handle was passed in.
+     *         UNSUPPORTED when the given configuration is not supported.
+     */
+    @callflow(next="*")
+    getClientTargetSupport_2_2(Display display,
+                               uint32_t width,
+                               uint32_t height,
+                               PixelFormat format,
+                               Dataspace dataspace)
+                    generates (Error error);
+    /**
      * setPowerMode_2_2
      * Sets the power mode of the given display. The transition must be
      * complete when this function returns. It is valid to call this function
@@ -260,4 +326,118 @@
      */
     setPowerMode_2_2(Display display, PowerMode mode) generates (Error error);
 
+    /**
+     * Returns the color modes supported on this display.
+     *
+     * All devices must support at least ColorMode::NATIVE.
+     *
+     * @param display is the display to query.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY when an invalid display handle was passed in.
+     * @return modes is an array of color modes.
+     */
+    getColorModes_2_2(Display display)
+           generates (Error error,
+                      vec<ColorMode> modes);
+
+    /**
+     * Returns the render intents supported by the specified display and color
+     * mode.
+     *
+     * RenderIntent::COLORIMETRIC is always supported.
+     *
+     * @param display is the display to query.
+     * @param mode is the color mode to query.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY when an invalid display handle was passed in.
+     *         BAD_PARAMETER when an invalid color mode was passed in.
+     * @return intents is an array of render intents.
+     */
+    getRenderIntents(Display display, ColorMode mode)
+          generates (Error error,
+                     vec<RenderIntent> intents);
+
+    /**
+     * Sets the color mode and render intent of the given display.
+     *
+     * The color mode and render intent change must take effect on next
+     * presentDisplay.
+     *
+     * All devices must support at least ColorMode::NATIVE and
+     * RenderIntent::COLORIMETRIC, and displays are assumed to be in this mode
+     * upon hotplug.
+     *
+     * @param display is the display to which the color mode is set.
+     * @param mode is the color mode to set to.
+     * @param intent is the render intent to set to.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY when an invalid display handle was passed in.
+     *         BAD_PARAMETER when mode or intent is invalid
+     *         UNSUPPORTED when mode or intent is not supported on this
+     *                     display.
+     */
+    setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent)
+          generates (Error error);
+
+    /*
+     * By default, layer dataspaces are mapped to the current color mode
+     * colorimetrically with a few exceptions.
+     *
+     * When the layer dataspace is a legacy sRGB dataspace
+     * (Dataspace::SRGB_LINEAR, Dataspace::SRGB, or Dataspace::UNKNOWN when
+     * treated as such) and the display render intent is
+     * RenderIntent::ENHANCE, the pixel values can go through an
+     * implementation-defined saturation transform before being mapped to the
+     * current color mode colorimetrically.
+     *
+     * Colors that are out of the gamut of the current color mode are
+     * hard-clipped.
+     */
+
+    /**
+     * Returns the saturation matrix of the specified legacy dataspace.
+     *
+     * The saturation matrix can be used to approximate the legacy dataspace
+     * saturation transform. It is to be applied on linear pixel values like
+     * this:
+     *
+     *   (in GLSL)
+     *   linearSrgb = clamp(saturationMatrix * linearSrgb, 0.0, 1.0);
+     *
+     * @param dataspace must be Dataspace::SRGB_LINEAR.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_PARAMETER when an invalid dataspace was passed in.
+     * @return matrix is the 4x4 column-major matrix used to approximate the
+     *         legacy dataspace saturation operation. The last row must be
+     *         [0.0, 0.0, 0.0, 1.0].
+     */
+    getDataspaceSaturationMatrix(Dataspace dataspace)
+                      generates (Error error,
+                                 float[4][4] matrix);
+
+    /**
+     * 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.
+     *
+     * @param inLength is the length of input commands.
+     * @param inHandles is an array of handles referenced by the input
+     *        commands.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_PARAMETER when inLength is not equal to the length of
+     *                       commands in the input command message queue.
+     *         NO_RESOURCES when the output command message queue was not
+     *                      properly drained.
+     * @param outQueueChanged indicates whether the output command message
+     *        queue has changed.
+     * @param outLength is the length of output commands.
+     * @param outHandles is an array of handles referenced by the output
+     *        commands.
+     */
+    executeCommands_2_2(uint32_t inLength,
+                        vec<handle> inHandles)
+             generates (Error error,
+                        bool outQueueChanged,
+                        uint32_t outLength,
+                        vec<handle> outHandles);
 };
diff --git a/graphics/composer/2.2/default/Android.bp b/graphics/composer/2.2/default/Android.bp
deleted file mode 100644
index 906479e..0000000
--- a/graphics/composer/2.2/default/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-cc_binary {
-    name: "android.hardware.graphics.composer@2.2-service",
-    defaults: ["hidl_defaults"],
-    vendor: true,
-    relative_install_path: "hw",
-    srcs: ["service.cpp"],
-    init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
-    header_libs: [
-        "android.hardware.graphics.composer@2.2-passthrough",
-    ],
-    shared_libs: [
-        "android.hardware.graphics.composer@2.1",
-        "android.hardware.graphics.composer@2.2",
-        "android.hardware.graphics.mapper@2.0",
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "libfmq",
-        "libhardware",
-        "libhidlbase",
-        "libhidltransport",
-        "libhwc2on1adapter",
-        "libhwc2onfbadapter",
-        "liblog",
-        "libsync",
-        "libutils",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"ComposerHal\""
-    ],
-}
diff --git a/graphics/composer/2.2/default/Android.mk b/graphics/composer/2.2/default/Android.mk
new file mode 100644
index 0000000..2f80f0c
--- /dev/null
+++ b/graphics/composer/2.2/default/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.graphics.composer@2.2-service
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_CFLAGS := -Wall -Werror -DLOG_TAG=\"ComposerHal\"
+LOCAL_SRC_FILES := service.cpp
+LOCAL_INIT_RC := android.hardware.graphics.composer@2.2-service.rc
+LOCAL_HEADER_LIBRARIES := android.hardware.graphics.composer@2.2-passthrough
+LOCAL_SHARED_LIBRARIES := \
+        android.hardware.graphics.composer@2.1 \
+        android.hardware.graphics.composer@2.2 \
+        android.hardware.graphics.mapper@2.0 \
+        libbase \
+        libbinder \
+        libcutils \
+        libfmq \
+        libhardware \
+        libhidlbase \
+        libhidltransport \
+        libhwc2on1adapter \
+        libhwc2onfbadapter \
+        liblog \
+        libsync \
+        libutils
+
+ifdef TARGET_USES_DISPLAY_RENDER_INTENTS
+LOCAL_CFLAGS += -DUSES_DISPLAY_RENDER_INTENTS
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index c803d3c..138d700 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -47,8 +47,8 @@
 
 using android::hardware::MessageQueue;
 using android::hardware::graphics::common::V1_0::ColorTransform;
-using android::hardware::graphics::common::V1_0::Dataspace;
 using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::common::V1_1::Dataspace;
 using android::hardware::graphics::composer::V2_1::Config;
 using android::hardware::graphics::composer::V2_1::Display;
 using android::hardware::graphics::composer::V2_1::Error;
@@ -64,6 +64,16 @@
    public:
     CommandWriterBase(uint32_t initialMaxSize) : V2_1::CommandWriterBase(initialMaxSize) {}
 
+    void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
+                         Dataspace dataspace, const std::vector<IComposerClient::Rect>& damage) {
+        setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
+                                damage);
+    }
+
+    void setLayerDataspace(Dataspace dataspace) {
+        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
+    }
+
     static constexpr uint16_t kSetLayerFloatColorLength = 4;
     void setLayerFloatColor(IComposerClient::FloatColor color) {
         beginCommand_2_2(IComposerClient::Command::SET_LAYER_FLOAT_COLOR,
@@ -72,8 +82,9 @@
         endCommand();
     }
 
-    void setPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
-        beginCommand_2_2(IComposerClient::Command::SET_PER_FRAME_METADATA, metadataVec.size() * 2);
+    void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
+        beginCommand_2_2(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
+                         metadataVec.size() * 2);
         for (const auto& metadata : metadataVec) {
             writeSigned(static_cast<int32_t>(metadata.key));
             writeFloat(metadata.value);
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
index d550f83..a6871fb 100644
--- a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerClient.h
@@ -99,10 +99,87 @@
         return mHal->setReadbackBuffer(display, readbackBuffer, std::move(fenceFd));
     }
 
+    Return<void> createVirtualDisplay_2_2(
+        uint32_t width, uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
+        IComposerClient::createVirtualDisplay_2_2_cb hidl_cb) override {
+        Display display = 0;
+        Error err = mHal->createVirtualDisplay_2_2(width, height, &formatHint, &display);
+        if (err == Error::NONE) {
+            mResources->addVirtualDisplay(display, outputBufferSlotCount);
+        }
+
+        hidl_cb(err, display, formatHint);
+        return Void();
+    }
+
+    Return<Error> getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
+                                             PixelFormat format, Dataspace dataspace) override {
+        Error err = mHal->getClientTargetSupport_2_2(display, width, height, format, dataspace);
+        return err;
+    }
+
     Return<Error> setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
         return mHal->setPowerMode_2_2(display, mode);
     }
 
+    Return<void> getColorModes_2_2(Display display,
+                                   IComposerClient::getColorModes_2_2_cb hidl_cb) override {
+        hidl_vec<ColorMode> modes;
+        Error err = mHal->getColorModes_2_2(display, &modes);
+        hidl_cb(err, modes);
+        return Void();
+    }
+
+    Return<void> getRenderIntents(Display display, ColorMode mode,
+                                  IComposerClient::getRenderIntents_cb hidl_cb) override {
+#ifdef USES_DISPLAY_RENDER_INTENTS
+        std::vector<RenderIntent> intents;
+        Error err = mHal->getRenderIntents(display, mode, &intents);
+        hidl_cb(err, intents);
+#else
+        (void)display;
+        (void)mode;
+        hidl_cb(Error::NONE, hidl_vec<RenderIntent>({RenderIntent::COLORIMETRIC}));
+#endif
+        return Void();
+    }
+
+    Return<Error> setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
+#ifndef USES_DISPLAY_RENDER_INTENTS
+        if (intent != RenderIntent::COLORIMETRIC) {
+            return Error::BAD_PARAMETER;
+        }
+#endif
+        return mHal->setColorMode_2_2(display, mode, intent);
+    }
+
+    Return<void> getDataspaceSaturationMatrix(
+        Dataspace dataspace, IComposerClient::getDataspaceSaturationMatrix_cb hidl_cb) override {
+        if (dataspace != Dataspace::SRGB_LINEAR) {
+            hidl_cb(Error::BAD_PARAMETER, std::array<float, 16>{0.0f}.data());
+            return Void();
+        }
+
+        hidl_cb(Error::NONE, mHal->getDataspaceSaturationMatrix(dataspace).data());
+        return Void();
+    }
+
+    Return<void> executeCommands_2_2(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles,
+                                     IComposerClient::executeCommands_2_2_cb hidl_cb) override {
+        std::lock_guard<std::mutex> lock(mCommandEngineMutex);
+        bool outChanged = false;
+        uint32_t outLength = 0;
+        hidl_vec<hidl_handle> outHandles;
+        Error error =
+            mCommandEngine->execute(inLength, inHandles, &outChanged, &outLength, &outHandles);
+
+        hidl_cb(error, outChanged, outLength, outHandles);
+
+        mCommandEngine->reset();
+
+        return Void();
+    }
+
    protected:
     std::unique_ptr<V2_1::hal::ComposerResources> createResources() override {
         return ComposerResources::create();
@@ -146,6 +223,8 @@
 
    private:
     using BaseType2_1 = V2_1::hal::detail::ComposerClientImpl<Interface, Hal>;
+    using BaseType2_1::mCommandEngine;
+    using BaseType2_1::mCommandEngineMutex;
     using BaseType2_1::mHal;
     using BaseType2_1::mResources;
 };
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
index adcac46..97e3a9e 100644
--- a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerCommandEngine.h
@@ -40,8 +40,8 @@
    protected:
     bool executeCommand(V2_1::IComposerClient::Command command, uint16_t length) override {
         switch (static_cast<IComposerClient::Command>(command)) {
-            case IComposerClient::Command::SET_PER_FRAME_METADATA:
-                return executeSetPerFrameMetadata(length);
+            case IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA:
+                return executeSetLayerPerFrameMetadata(length);
             case IComposerClient::Command::SET_LAYER_FLOAT_COLOR:
                 return executeSetLayerFloatColor(length);
             default:
@@ -49,7 +49,7 @@
         }
     }
 
-    bool executeSetPerFrameMetadata(uint16_t length) {
+    bool executeSetLayerPerFrameMetadata(uint16_t length) {
         // (key, value) pairs
         if (length % 2 != 0) {
             return false;
@@ -63,7 +63,7 @@
             length -= 2;
         }
 
-        auto err = mHal->setPerFrameMetadata(mCurrentDisplay, metadata);
+        auto err = mHal->setLayerPerFrameMetadata(mCurrentDisplay, mCurrentLayer, metadata);
         if (err != Error::NONE) {
             mWriter.setError(getCommandLoc(), err);
         }
diff --git a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
index 30b3643..335dc24 100644
--- a/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
+++ b/graphics/composer/2.2/utils/hal/include/composer-hal/2.2/ComposerHal.h
@@ -28,34 +28,68 @@
 namespace V2_2 {
 namespace hal {
 
-using common::V1_0::Dataspace;
-using common::V1_0::PixelFormat;
+using common::V1_1::ColorMode;
+using common::V1_1::Dataspace;
+using common::V1_1::PixelFormat;
+using common::V1_1::RenderIntent;
 using V2_1::Display;
 using V2_1::Error;
 using V2_1::Layer;
 
 class ComposerHal : public V2_1::hal::ComposerHal {
    public:
+    Error createVirtualDisplay(uint32_t width, uint32_t height, common::V1_0::PixelFormat* format,
+                               Display* outDisplay) override {
+        return createVirtualDisplay_2_2(width, height, reinterpret_cast<PixelFormat*>(format),
+                                        outDisplay);
+    }
+    Error getClientTargetSupport(Display display, uint32_t width, uint32_t height,
+                                 common::V1_0::PixelFormat format,
+                                 common::V1_0::Dataspace dataspace) override {
+        return getClientTargetSupport_2_2(display, width, height, static_cast<PixelFormat>(format),
+                                          static_cast<Dataspace>(dataspace));
+    }
     // superceded by setPowerMode_2_2
     Error setPowerMode(Display display, V2_1::IComposerClient::PowerMode mode) override {
         return setPowerMode_2_2(display, static_cast<IComposerClient::PowerMode>(mode));
     }
 
+    // superceded by getColorModes_2_2
+    Error getColorModes(Display display, hidl_vec<common::V1_0::ColorMode>* outModes) override {
+        return getColorModes_2_2(display, reinterpret_cast<hidl_vec<ColorMode>*>(outModes));
+    }
+
+    // superceded by setColorMode_2_2
+    Error setColorMode(Display display, common::V1_0::ColorMode mode) override {
+        return setColorMode_2_2(display, static_cast<ColorMode>(mode), RenderIntent::COLORIMETRIC);
+    }
+
     virtual Error getPerFrameMetadataKeys(
         Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
-    virtual Error setPerFrameMetadata(
-        Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
+    virtual Error setLayerPerFrameMetadata(
+        Display display, Layer layer,
+        const std::vector<IComposerClient::PerFrameMetadata>& metadata) = 0;
 
     virtual Error getReadbackBufferAttributes(Display display, PixelFormat* outFormat,
                                               Dataspace* outDataspace) = 0;
     virtual Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
                                     base::unique_fd fenceFd) = 0;
     virtual Error getReadbackBufferFence(Display display, base::unique_fd* outFenceFd) = 0;
-
+    virtual Error createVirtualDisplay_2_2(uint32_t width, uint32_t height, PixelFormat* format,
+                                           Display* outDisplay) = 0;
+    virtual Error getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
+                                             PixelFormat format, Dataspace dataspace) = 0;
     virtual Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) = 0;
 
     virtual Error setLayerFloatColor(Display display, Layer layer,
                                      IComposerClient::FloatColor color) = 0;
+
+    virtual Error getColorModes_2_2(Display display, hidl_vec<ColorMode>* outModes) = 0;
+    virtual Error getRenderIntents(Display display, ColorMode mode,
+                                   std::vector<RenderIntent>* outIntents) = 0;
+    virtual Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) = 0;
+
+    virtual std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace) = 0;
 };
 
 }  // namespace hal
diff --git a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
index b251351..93da0a5 100644
--- a/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
+++ b/graphics/composer/2.2/utils/passthrough/include/composer-passthrough/2.2/HwcHal.h
@@ -34,8 +34,10 @@
 
 namespace detail {
 
-using common::V1_0::Dataspace;
-using common::V1_0::PixelFormat;
+using common::V1_1::ColorMode;
+using common::V1_1::Dataspace;
+using common::V1_1::PixelFormat;
+using common::V1_1::RenderIntent;
 using V2_1::Display;
 using V2_1::Error;
 using V2_1::Layer;
@@ -72,9 +74,10 @@
         return Error::NONE;
     }
 
-    Error setPerFrameMetadata(
-        Display display, const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
-        if (!mDispatch.setPerFrameMetadata) {
+    Error setLayerPerFrameMetadata(
+        Display display, Layer layer,
+        const std::vector<IComposerClient::PerFrameMetadata>& metadata) override {
+        if (!mDispatch.setLayerPerFrameMetadata) {
             return Error::UNSUPPORTED;
         }
 
@@ -87,8 +90,8 @@
             values.push_back(m.value);
         }
 
-        int32_t error = mDispatch.setPerFrameMetadata(mDevice, display, metadata.size(),
-                                                      keys.data(), values.data());
+        int32_t error = mDispatch.setLayerPerFrameMetadata(mDevice, display, layer, metadata.size(),
+                                                           keys.data(), values.data());
         return static_cast<Error>(error);
     }
 
@@ -131,6 +134,19 @@
         return static_cast<Error>(error);
     }
 
+    Error createVirtualDisplay_2_2(uint32_t width, uint32_t height, PixelFormat* format,
+                                   Display* outDisplay) override {
+        return createVirtualDisplay(
+            width, height, reinterpret_cast<common::V1_0::PixelFormat*>(format), outDisplay);
+    }
+
+    Error getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
+                                     PixelFormat format, Dataspace dataspace) override {
+        return getClientTargetSupport(display, width, height,
+                                      static_cast<common::V1_0::PixelFormat>(format),
+                                      static_cast<common::V1_0::Dataspace>(dataspace));
+    }
+
     Error setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) override {
         if (mode == IComposerClient::PowerMode::ON_SUSPEND) {
             return Error::UNSUPPORTED;
@@ -149,6 +165,69 @@
         return static_cast<Error>(error);
     }
 
+    Error getColorModes_2_2(Display display, hidl_vec<ColorMode>* outModes) override {
+        return getColorModes(display,
+                             reinterpret_cast<hidl_vec<common::V1_0::ColorMode>*>(outModes));
+    }
+
+    Error getRenderIntents(Display display, ColorMode mode,
+                           std::vector<RenderIntent>* outIntents) override {
+        if (!mDispatch.getRenderIntents) {
+            *outIntents = std::vector<RenderIntent>({RenderIntent::COLORIMETRIC});
+            return Error::NONE;
+        }
+
+        uint32_t count = 0;
+        int32_t error =
+            mDispatch.getRenderIntents(mDevice, display, int32_t(mode), &count, nullptr);
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+
+        std::vector<RenderIntent> intents(count);
+        error = mDispatch.getRenderIntents(
+            mDevice, display, int32_t(mode), &count,
+            reinterpret_cast<std::underlying_type<RenderIntent>::type*>(intents.data()));
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast<Error>(error);
+        }
+        intents.resize(count);
+
+        *outIntents = std::move(intents);
+        return Error::NONE;
+    }
+
+    Error setColorMode_2_2(Display display, ColorMode mode, RenderIntent intent) override {
+        if (!mDispatch.setColorModeWithRenderIntent) {
+            if (intent != RenderIntent::COLORIMETRIC) {
+                return Error::UNSUPPORTED;
+            }
+            return setColorMode(display, static_cast<common::V1_0::ColorMode>(mode));
+        }
+
+        int32_t err = mDispatch.setColorModeWithRenderIntent(
+            mDevice, display, static_cast<int32_t>(mode), static_cast<int32_t>(intent));
+        return static_cast<Error>(err);
+    }
+
+    std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace) override {
+        std::array<float, 16> matrix;
+
+        int32_t error = HWC2_ERROR_UNSUPPORTED;
+        if (mDispatch.getDataspaceSaturationMatrix) {
+            error = mDispatch.getDataspaceSaturationMatrix(mDevice, static_cast<int32_t>(dataspace),
+                                                           matrix.data());
+        }
+        if (error != HWC2_ERROR_NONE) {
+            return std::array<float, 16>{
+                1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
+                0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+            };
+        }
+
+        return matrix;
+    }
+
    protected:
     template <typename T>
     bool initOptionalDispatch(hwc2_function_descriptor_t desc, T* outPfn) {
@@ -168,7 +247,8 @@
 
         initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, &mDispatch.setLayerFloatColor);
 
-        initOptionalDispatch(HWC2_FUNCTION_SET_PER_FRAME_METADATA, &mDispatch.setPerFrameMetadata);
+        initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA,
+                             &mDispatch.setLayerPerFrameMetadata);
         initOptionalDispatch(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS,
                              &mDispatch.getPerFrameMetadataKeys);
 
@@ -178,21 +258,34 @@
         initOptionalDispatch(HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE,
                              &mDispatch.getReadbackBufferFence);
 
+        initOptionalDispatch(HWC2_FUNCTION_GET_RENDER_INTENTS, &mDispatch.getRenderIntents);
+        initOptionalDispatch(HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT,
+                             &mDispatch.setColorModeWithRenderIntent);
+        initOptionalDispatch(HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX,
+                             &mDispatch.getDataspaceSaturationMatrix);
+
         return true;
     }
 
     struct {
         HWC2_PFN_SET_LAYER_FLOAT_COLOR setLayerFloatColor;
-        HWC2_PFN_SET_PER_FRAME_METADATA setPerFrameMetadata;
+        HWC2_PFN_SET_LAYER_PER_FRAME_METADATA setLayerPerFrameMetadata;
         HWC2_PFN_GET_PER_FRAME_METADATA_KEYS getPerFrameMetadataKeys;
         HWC2_PFN_SET_READBACK_BUFFER setReadbackBuffer;
         HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES getReadbackBufferAttributes;
         HWC2_PFN_GET_READBACK_BUFFER_FENCE getReadbackBufferFence;
+        HWC2_PFN_GET_RENDER_INTENTS getRenderIntents;
+        HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT setColorModeWithRenderIntent;
+        HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX getDataspaceSaturationMatrix;
     } mDispatch = {};
 
    private:
     using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
+    using BaseType2_1::getColorModes;
     using BaseType2_1::mDevice;
+    using BaseType2_1::setColorMode;
+    using BaseType2_1::createVirtualDisplay;
+    using BaseType2_1::getClientTargetSupport;
     using BaseType2_1::setPowerMode;
 };
 
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 641fdcb..c6b524d 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -26,10 +26,17 @@
         "android.hardware.graphics.composer@2.1-vts",
         "android.hardware.graphics.composer@2.2",
     ],
+    export_static_lib_headers: [
+        "android.hardware.graphics.composer@2.1-vts",
+    ],
     header_libs: [
         "android.hardware.graphics.composer@2.1-command-buffer",
         "android.hardware.graphics.composer@2.2-command-buffer",
     ],
+    export_header_lib_headers: [
+        "android.hardware.graphics.composer@2.1-command-buffer",
+        "android.hardware.graphics.composer@2.2-command-buffer",
+    ],
     cflags: [
         "-O0",
         "-g",
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index b536f67..357c772 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -87,6 +87,33 @@
                                   });
 }
 
+Display ComposerClient_v2_2::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
+                                                      PixelFormat formatHint,
+                                                      uint32_t outputBufferSlotCount,
+                                                      PixelFormat* outFormat) {
+    Display display = 0;
+    mClient_v2_2->createVirtualDisplay_2_2(
+        width, height, formatHint, outputBufferSlotCount,
+        [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
+            display = tmpDisplay;
+            *outFormat = tmpFormat;
+
+            ASSERT_TRUE(mDisplayResources.insert({display, DisplayResource(true)}).second)
+                << "duplicated virtual display id " << display;
+        });
+
+    return display;
+}
+
+bool ComposerClient_v2_2::getClientTargetSupport_2_2(Display display, uint32_t width,
+                                                     uint32_t height, PixelFormat format,
+                                                     Dataspace dataspace) {
+    Error error =
+        mClient_v2_2->getClientTargetSupport_2_2(display, width, height, format, dataspace);
+    return error == Error::NONE;
+}
+
 void ComposerClient_v2_2::setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode) {
     Error error = mClient_v2_2->setPowerMode_2_2(display, mode);
     ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set power mode";
@@ -119,6 +146,41 @@
     *outFence = 0;
 }
 
+std::vector<ColorMode> ComposerClient_v2_2::getColorModes(Display display) {
+    std::vector<ColorMode> modes;
+    mClient_v2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color modes";
+        modes = tmpModes;
+    });
+    return modes;
+}
+
+std::vector<RenderIntent> ComposerClient_v2_2::getRenderIntents(Display display, ColorMode mode) {
+    std::vector<RenderIntent> intents;
+    mClient_v2_2->getRenderIntents(
+        display, mode, [&](const auto& tmpError, const auto& tmpIntents) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get render intents";
+            intents = tmpIntents;
+        });
+    return intents;
+}
+
+void ComposerClient_v2_2::setColorMode(Display display, ColorMode mode, RenderIntent intent) {
+    Error error = mClient_v2_2->setColorMode_2_2(display, mode, intent);
+    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set color mode";
+}
+
+std::array<float, 16> ComposerClient_v2_2::getDataspaceSaturationMatrix(Dataspace dataspace) {
+    std::array<float, 16> matrix;
+    mClient_v2_2->getDataspaceSaturationMatrix(
+        dataspace, [&](const auto& tmpError, const auto& tmpMatrix) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get datasapce saturation matrix";
+            std::copy_n(tmpMatrix.data(), matrix.size(), matrix.begin());
+        });
+
+    return matrix;
+}
+
 }  // namespace vts
 }  // namespace V2_2
 }  // namespace composer
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index eced69f..62ab83f 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -36,10 +36,11 @@
 namespace V2_2 {
 namespace vts {
 
-using android::hardware::graphics::common::V1_0::ColorMode;
-using android::hardware::graphics::common::V1_0::Dataspace;
 using android::hardware::graphics::common::V1_0::Hdr;
-using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_1::ColorMode;
+using android::hardware::graphics::common::V1_1::Dataspace;
+using android::hardware::graphics::common::V1_1::PixelFormat;
+using android::hardware::graphics::common::V1_1::RenderIntent;
 using android::hardware::graphics::composer::V2_2::IComposer;
 using android::hardware::graphics::composer::V2_2::IComposerClient;
 
@@ -66,12 +67,22 @@
 
     std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys(Display display);
 
+    Display createVirtualDisplay_2_2(uint32_t width, uint32_t height, PixelFormat formatHint,
+                                     uint32_t outputBufferSlotCount, PixelFormat* outFormat);
+    bool getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
+                                    PixelFormat format, Dataspace dataspace);
     void setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode);
     void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence);
     void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                      Dataspace* outDataspace);
     void getReadbackBufferFence(Display display, int32_t* outFence);
 
+    std::vector<ColorMode> getColorModes(Display display);
+    std::vector<RenderIntent> getRenderIntents(Display display, ColorMode mode);
+    void setColorMode(Display display, ColorMode mode, RenderIntent intent);
+
+    std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace);
+
    private:
     sp<V2_2::IComposerClient> mClient_v2_2;
 };
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 7747900..669fbae 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -27,6 +27,7 @@
     ],
     static_libs: [
         "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.common@1.1",
         "android.hardware.graphics.composer@2.1",
         "android.hardware.graphics.composer@2.1-vts",
         "android.hardware.graphics.composer@2.2",
@@ -34,6 +35,7 @@
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.0-vts",
         "android.hardware.graphics.mapper@2.1",
+        "android.hardware.graphics.mapper@2.1-vts",
     ],
     header_libs: [
         "android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index c494329..4e41333 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -22,7 +22,7 @@
 #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.0/MapperVts.h>
+#include <mapper-vts/2.1/MapperVts.h>
 
 namespace android {
 namespace hardware {
@@ -33,14 +33,15 @@
 namespace {
 
 using android::hardware::graphics::common::V1_0::BufferUsage;
-using android::hardware::graphics::common::V1_0::ColorMode;
 using android::hardware::graphics::common::V1_0::ColorTransform;
-using android::hardware::graphics::common::V1_0::Dataspace;
-using android::hardware::graphics::common::V1_0::PixelFormat;
 using android::hardware::graphics::common::V1_0::Transform;
+using android::hardware::graphics::common::V1_1::ColorMode;
+using android::hardware::graphics::common::V1_1::Dataspace;
+using android::hardware::graphics::common::V1_1::PixelFormat;
+using android::hardware::graphics::common::V1_1::RenderIntent;
 using android::hardware::graphics::composer::V2_2::IComposerClient;
-using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::vts::Gralloc;
+using android::hardware::graphics::mapper::V2_1::IMapper;
+using android::hardware::graphics::mapper::V2_1::vts::Gralloc;
 using GrallocError = android::hardware::graphics::mapper::V2_0::Error;
 
 // Test environment for graphics.composer
@@ -146,9 +147,9 @@
 };
 
 /**
- * Test IComposerClient::Command::SET_PER_FRAME_METADATA.
+ * Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
  */
-TEST_F(GraphicsComposerHidlCommandTest, SET_PER_FRAME_METADATA) {
+TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
     Layer layer;
     ASSERT_NO_FATAL_FAILURE(layer =
                                 mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
@@ -182,7 +183,7 @@
     hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
     hidlMetadata.push_back(
         {IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
-    mWriter->setPerFrameMetadata(hidlMetadata);
+    mWriter->setLayerPerFrameMetadata(hidlMetadata);
     execute();
 }
 
@@ -192,6 +193,55 @@
 TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
     mComposerClient->getPerFrameMetadataKeys(mPrimaryDisplay);
 }
+
+/**
+ * Test IComposerClient::createVirtualDisplay_2_2 and
+ * IComposerClient::destroyVirtualDisplay.
+ *
+ * Test that virtual displays can be created and has the correct display type.
+ */
+TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
+    if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
+        GTEST_SUCCEED() << "no virtual display support";
+        return;
+    }
+
+    Display display;
+    PixelFormat format;
+    ASSERT_NO_FATAL_FAILURE(
+        display = mComposerClient->createVirtualDisplay_2_2(
+            64, 64, PixelFormat::IMPLEMENTATION_DEFINED, kBufferSlotCount, &format));
+
+    // test display type
+    IComposerClient::DisplayType type = mComposerClient->getDisplayType(display);
+    EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type);
+
+    mComposerClient->destroyVirtualDisplay(display);
+}
+
+/**
+ * Test IComposerClient::getClientTargetSupport_2_2.
+ *
+ * Test that IComposerClient::getClientTargetSupport returns true for the
+ * required client targets.
+ */
+TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
+    std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
+    for (auto config : configs) {
+        int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+                                                             IComposerClient::Attribute::WIDTH);
+        int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
+                                                              IComposerClient::Attribute::HEIGHT);
+        ASSERT_LT(0, width);
+        ASSERT_LT(0, height);
+
+        mComposerClient->setActiveConfig(mPrimaryDisplay, config);
+
+        ASSERT_TRUE(mComposerClient->getClientTargetSupport_2_2(
+            mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN));
+    }
+}
+
 /**
  * Test IComposerClient::setPowerMode_2_2.
  */
@@ -235,6 +285,56 @@
     mWriter->setLayerFloatColor(IComposerClient::FloatColor{0.0, 0.0, 0.0, 0.0});
 }
 
+/**
+ * Test IComposerClient::getDataspaceSaturationMatrix.
+ */
+TEST_F(GraphicsComposerHidlTest, getDataspaceSaturationMatrix) {
+    auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
+    // the last row is known
+    ASSERT_EQ(0.0f, matrix[12]);
+    ASSERT_EQ(0.0f, matrix[13]);
+    ASSERT_EQ(0.0f, matrix[14]);
+    ASSERT_EQ(1.0f, matrix[15]);
+}
+
+/**
+ * Test IComposerClient::getColorMode_2_2.
+ */
+TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2) {
+    std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
+
+    auto nativeMode = std::find(modes.cbegin(), modes.cend(), ColorMode::NATIVE);
+    EXPECT_NE(modes.cend(), nativeMode);
+}
+
+/**
+ * Test IComposerClient::getRenderIntent.
+ */
+TEST_F(GraphicsComposerHidlTest, GetRenderIntent) {
+    std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
+    for (auto mode : modes) {
+        std::vector<RenderIntent> intents =
+            mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
+        auto colorimetricIntent =
+            std::find(intents.cbegin(), intents.cend(), RenderIntent::COLORIMETRIC);
+        EXPECT_NE(intents.cend(), colorimetricIntent);
+    }
+}
+
+/**
+ * Test IComposerClient::setColorMode_2_2.
+ */
+TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2) {
+    std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
+    for (auto mode : modes) {
+        std::vector<RenderIntent> intents =
+            mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
+        for (auto intent : intents) {
+            mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
+        }
+    }
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_2
diff --git a/graphics/mapper/2.1/utils/vts/MapperVts.cpp b/graphics/mapper/2.1/utils/vts/MapperVts.cpp
index 0aaa926..078068e 100644
--- a/graphics/mapper/2.1/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/2.1/utils/vts/MapperVts.cpp
@@ -43,6 +43,13 @@
                       offsetof(IMapper::BufferDescriptorInfo, usage),
               "");
 
+Gralloc::Gralloc() : V2_0::vts::Gralloc() {
+    if (::testing::Test::HasFatalFailure()) {
+        return;
+    }
+    init();
+}
+
 Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName)
     : V2_0::vts::Gralloc(allocatorServiceName, mapperServiceName) {
     if (::testing::Test::HasFatalFailure()) {
diff --git a/graphics/mapper/2.1/utils/vts/include/mapper-vts/2.1/MapperVts.h b/graphics/mapper/2.1/utils/vts/include/mapper-vts/2.1/MapperVts.h
index b7fa751..423d4b3 100644
--- a/graphics/mapper/2.1/utils/vts/include/mapper-vts/2.1/MapperVts.h
+++ b/graphics/mapper/2.1/utils/vts/include/mapper-vts/2.1/MapperVts.h
@@ -32,6 +32,7 @@
 // A wrapper to IAllocator and IMapper.
 class Gralloc : public V2_0::vts::Gralloc {
    public:
+    Gralloc();
     Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName);
 
     sp<IMapper> getMapper() const;
diff --git a/keymaster/4.0/support/Keymaster.cpp b/keymaster/4.0/support/Keymaster.cpp
index bf52c47..fac0017 100644
--- a/keymaster/4.0/support/Keymaster.cpp
+++ b/keymaster/4.0/support/Keymaster.cpp
@@ -40,7 +40,7 @@
     serviceManager->listByInterface(descriptor, [&](const hidl_vec<hidl_string>& names) {
         for (auto& name : names) {
             if (name == "default") foundDefault = true;
-            auto device = Wrapper::WrappedIKeymasterDevice::getService();
+            auto device = Wrapper::WrappedIKeymasterDevice::getService(name);
             CHECK(device) << "Failed to get service for " << descriptor << " with interface name "
                           << name;
             result.push_back(std::unique_ptr<Keymaster>(new Wrapper(device, name)));
diff --git a/radio/1.2/Android.bp b/radio/1.2/Android.bp
index a9c80b7..c90a03c 100644
--- a/radio/1.2/Android.bp
+++ b/radio/1.2/Android.bp
@@ -24,6 +24,7 @@
         "Call",
         "CardStatus",
         "CellConnectionStatus",
+        "CellIdentity",
         "CellIdentityCdma",
         "CellIdentityGsm",
         "CellIdentityLte",
@@ -36,6 +37,7 @@
         "CellInfoLte",
         "CellInfoTdscdma",
         "CellInfoWcdma",
+        "DataRegStateResult",
         "DataRequestReason",
         "IncrementalResultsPeriodicityRange",
         "IndicationFilter",
@@ -48,6 +50,7 @@
         "ScanIntervalRange",
         "SignalStrength",
         "TdscdmaSignalStrength",
+        "VoiceRegStateResult",
         "WcdmaSignalStrength",
     ],
     gen_java: true,
diff --git a/radio/1.2/IRadioResponse.hal b/radio/1.2/IRadioResponse.hal
index f26c9ec..300aa37 100644
--- a/radio/1.2/IRadioResponse.hal
+++ b/radio/1.2/IRadioResponse.hal
@@ -98,4 +98,31 @@
      *   RadioError:INTERNAL_ERR
      */
     oneway getSignalStrengthResponse_1_2(RadioResponseInfo info, SignalStrength signalStrength);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param voiceRegResponse Current Voice registration response as defined by VoiceRegStateResult
+     *        in types.hal
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     */
+    oneway getVoiceRegistrationStateResponse_1_2(RadioResponseInfo info,
+            VoiceRegStateResult voiceRegResponse);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param dataRegResponse Current Data registration response as defined by DataRegStateResult in
+     *        types.hal
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:NOT_PROVISIONED
+     */
+    oneway getDataRegistrationStateResponse_1_2(RadioResponseInfo info,
+            DataRegStateResult dataRegResponse);
 };
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index 5e72b3b..4715fac 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -32,6 +32,7 @@
 import @1.0::LteSignalStrength;
 import @1.0::RadioConst;
 import @1.0::RadioError;
+import @1.0::RegState;
 import @1.0::SignalStrength;
 import @1.0::TdScdmaSignalStrength;
 import @1.0::TimeStampType;
@@ -462,3 +463,129 @@
     TdScdmaSignalStrength tdScdma;
     WcdmaSignalStrength wcdma;
 };
+
+struct CellIdentity {
+    /**
+     * Cell type for selecting from union CellInfo.
+     * Only one of the below vectors must be of size 1 based on a
+     * valid CellInfoType and others must be of size 0.
+     * If cell info type is NONE, then all the vectors must be of size 0.
+     */
+    CellInfoType cellInfoType;
+    vec<CellIdentityGsm> cellIdentityGsm;
+    vec<CellIdentityWcdma> cellIdentityWcdma;
+    vec<CellIdentityCdma> cellIdentityCdma;
+    vec<CellIdentityLte> cellIdentityLte;
+    vec<CellIdentityTdscdma> cellIdentityTdscdma;
+};
+
+struct VoiceRegStateResult {
+    /**
+     * Valid reg states are NOT_REG_MT_NOT_SEARCHING_OP,
+     * REG_HOME, NOT_REG_MT_SEARCHING_OP, REG_DENIED,
+     * UNKNOWN, REG_ROAMING defined in RegState
+     */
+    RegState regState;
+    /**
+     * Indicates the available voice radio technology, valid values as
+     * defined by RadioTechnology.
+     */
+    int32_t rat;
+    /**
+     * concurrent services support indicator. if registered on a CDMA system.
+     * false - Concurrent services not supported,
+     * true - Concurrent services supported
+     */
+    bool cssSupported;
+    /**
+     * TSB-58 Roaming Indicator if registered on a CDMA or EVDO system or -1 if not.
+     * Valid values are 0-255.
+     */
+    int32_t roamingIndicator;
+    /**
+     * Indicates whether the current system is in the PRL if registered on a CDMA or EVDO system
+     * or -1 if not. 0=not in the PRL, 1=in the PRL
+     */
+    int32_t systemIsInPrl;
+    /**
+     * Default Roaming Indicator from the PRL if registered on a CDMA or EVDO system or -1 if not.
+     * Valid values are 0-255.
+     */
+    int32_t defaultRoamingIndicator;
+    /**
+     * reasonForDenial if registration state is 3
+     * (Registration denied) this is an enumerated reason why
+     * registration was denied. See 3GPP TS 24.008,
+     * 10.5.3.6 and Annex G.
+     * 0 - General
+     * 1 - Authentication Failure
+     * 2 - IMSI unknown in HLR
+     * 3 - Illegal MS
+     * 4 - Illegal ME
+     * 5 - PLMN not allowed
+     * 6 - Location area not allowed
+     * 7 - Roaming not allowed
+     * 8 - No Suitable Cells in this Location Area
+     * 9 - Network failure
+     * 10 - Persistent location update reject
+     * 11 - PLMN not allowed
+     * 12 - Location area not allowed
+     * 13 - Roaming not allowed in this Location Area
+     * 15 - No Suitable Cells in this Location Area
+     * 17 - Network Failure
+     * 20 - MAC Failure
+     * 21 - Sync Failure
+     * 22 - Congestion
+     * 23 - GSM Authentication unacceptable
+     * 25 - Not Authorized for this CSG
+     * 32 - Service option not supported
+     * 33 - Requested service option not subscribed
+     * 34 - Service option temporarily out of order
+     * 38 - Call cannot be identified
+     * 48-63 - Retry upon entry into a new cell
+     * 95 - Semantically incorrect message
+     * 96 - Invalid mandatory information
+     * 97 - Message type non-existent or not implemented
+     * 98 - Message type not compatible with protocol state
+     * 99 - Information element non-existent or not implemented
+     * 100 - Conditional IE error
+     * 101 - Message not compatible with protocol state
+     * 111 - Protocol error, unspecified
+     */
+    int32_t reasonForDenial;
+
+    CellIdentity cellIdentity;
+};
+
+struct DataRegStateResult {
+    /**
+     * Valid reg states are NOT_REG_MT_NOT_SEARCHING_OP,
+     * REG_HOME, NOT_REG_MT_SEARCHING_OP, REG_DENIED,
+     * UNKNOWN, REG_ROAMING defined in RegState
+     */
+    RegState regState;
+    /**
+     * Indicates the available data radio technology,
+     * valid values as defined by RadioTechnology.
+     */
+    int32_t rat;
+    /**
+     * If registration state is 3 (Registration
+     * denied) this is an enumerated reason why
+     * registration was denied. See 3GPP TS 24.008,
+     * Annex G.6 "Additional cause codes for GMM".
+     * 7 == GPRS services not allowed
+     * 8 == GPRS services and non-GPRS services not allowed
+     * 9 == MS identity cannot be derived by the network
+     * 10 == Implicitly detached
+     * 14 == GPRS services not allowed in this PLMN
+     * 16 == MSC temporarily not reachable
+     * 40 == No PDP context activated
+     */
+    int32_t reasonDataDenied;
+    /**
+     * The maximum number of simultaneous Data Calls must be established using setupDataCall().
+     */
+    int32_t maxDataCalls;
+    CellIdentity cellIdentity;
+};
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index 34a87e1..ee130f8 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -673,3 +673,40 @@
     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
                                  {RadioError::NONE, RadioError::NO_NETWORK_FOUND}));
 }
+
+/*
+ * Test IRadio.getVoiceRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, getVoiceRegistrationState) {
+    int serial = GetRandomSerialNumber();
+
+    Return<void> res = radio_v1_2->getVoiceRegistrationState(serial);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+    ALOGI("getVoiceRegistrationStateResponse_1_2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_2->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
+}
+
+/*
+ * Test IRadio.getDataRegistrationState() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_2, getDataRegistrationState) {
+    int serial = GetRandomSerialNumber();
+
+    Return<void> res = radio_v1_2->getDataRegistrationState(serial);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+
+    ALOGI("getVoiceRegistrationStateResponse_1_2, rspInfo.error = %s\n",
+          toString(radioRsp_v1_2->rspInfo.error).c_str());
+    ASSERT_TRUE(CheckAnyOfErrors(
+        radioRsp_v1_2->rspInfo.error,
+        {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NOT_PROVISIONED}));
+}
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index 66d8ca4..c61913c 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -417,6 +417,12 @@
 
     Return<void> getCellInfoListResponse_1_2(
         const RadioResponseInfo& info, const ::android::hardware::hidl_vec<CellInfo>& cellInfo);
+
+    Return<void> getVoiceRegistrationStateResponse_1_2(
+        const RadioResponseInfo& info, const V1_2::VoiceRegStateResult& voiceRegResponse);
+
+    Return<void> getDataRegistrationStateResponse_1_2(
+        const RadioResponseInfo& info, const V1_2::DataRegStateResult& dataRegResponse);
 };
 
 /* Callback class for radio indication */
diff --git a/radio/1.2/vts/functional/radio_response.cpp b/radio/1.2/vts/functional/radio_response.cpp
index d96f76b..9195689 100644
--- a/radio/1.2/vts/functional/radio_response.cpp
+++ b/radio/1.2/vts/functional/radio_response.cpp
@@ -731,4 +731,14 @@
     rspInfo = info;
     parent_v1_2.notify();
     return Void();
-}
\ No newline at end of file
+}
+
+Return<void> RadioResponse_v1_2::getVoiceRegistrationStateResponse_1_2(
+    const RadioResponseInfo& /*info*/, const V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_2::getDataRegistrationStateResponse_1_2(
+    const RadioResponseInfo& /*info*/, const V1_2::DataRegStateResult& /*dataRegResponse*/) {
+    return Void();
+}
diff --git a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
index 59c354f..dab81e2 100644
--- a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
+++ b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
@@ -34,14 +34,13 @@
 using ::android::sp;
 using ::testing::VtsHalHidlTargetTestEnvBase;
 
-#define SELECT_ISD \
-    { 0x00, 0xA4, 0x04, 0x00, 0x00 }
-#define SEQUENCE_COUNTER \
-    { 0x80, 0xCA, 0x00, 0xC1, 0x00 }
-#define MANAGE_SELECT \
-    { 0x00, 0xA4, 0x04, 0x00, 0x00 }
-#define CRS_AID \
-    { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x43, 0x52, 0x53, 0x00 }
+#define DATA_APDU \
+    { 0x00, 0x08, 0x00, 0x00, 0x00 }
+#define ANDROID_TEST_AID                                                                          \
+    {                                                                                             \
+        0xA0, 0x00, 0x00, 0x04, 0x76, 0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64, 0x43, 0x54, 0x53, \
+            0x31                                                                                  \
+    }
 
 constexpr char kCallbackNameOnStateChange[] = "onStateChange";
 
@@ -115,7 +114,7 @@
  * Check status word in the response
  */
 TEST_F(SecureElementHidlTest, transmit) {
-    std::vector<uint8_t> aid = CRS_AID;
+    std::vector<uint8_t> aid = ANDROID_TEST_AID;
     SecureElementStatus statusReturned;
     LogicalChannelResponse response;
     se_->openLogicalChannel(
@@ -132,9 +131,9 @@
             }
         });
     EXPECT_EQ(SecureElementStatus::SUCCESS, statusReturned);
-    EXPECT_LE((unsigned int)3, response.selectResponse.size());
+    EXPECT_LE((unsigned int)2, response.selectResponse.size());
     EXPECT_LE(1, response.channelNumber);
-    std::vector<uint8_t> command = SELECT_ISD;
+    std::vector<uint8_t> command = DATA_APDU;
     std::vector<uint8_t> transmitResponse;
     se_->transmit(command, [&transmitResponse](std::vector<uint8_t> res) {
         transmitResponse.resize(res.size());
@@ -145,16 +144,6 @@
     EXPECT_LE((unsigned int)3, transmitResponse.size());
     EXPECT_EQ(0x90, transmitResponse[transmitResponse.size() - 2]);
     EXPECT_EQ(0x00, transmitResponse[transmitResponse.size() - 1]);
-    command = SEQUENCE_COUNTER;
-    se_->transmit(command, [&transmitResponse](std::vector<uint8_t> res) {
-        transmitResponse.resize(res.size());
-        for (size_t i = 0; i < res.size(); i++) {
-            transmitResponse[i] = res[i];
-        }
-    });
-    EXPECT_LE((unsigned int)3, transmitResponse.size());
-    EXPECT_EQ(0x90, transmitResponse[transmitResponse.size() - 2]);
-    EXPECT_EQ(0x00, transmitResponse[transmitResponse.size() - 1]);
     EXPECT_EQ(SecureElementStatus::SUCCESS, se_->closeChannel(response.channelNumber));
 }
 
@@ -164,7 +153,7 @@
  *  open channel, check the length of selectResponse and close the channel
  */
 TEST_F(SecureElementHidlTest, openBasicChannel) {
-    std::vector<uint8_t> aid = CRS_AID;
+    std::vector<uint8_t> aid = ANDROID_TEST_AID;
     SecureElementStatus statusReturned;
     std::vector<uint8_t> response;
     se_->openBasicChannel(aid, 0x00,
@@ -180,17 +169,6 @@
                           });
     if (statusReturned == SecureElementStatus::SUCCESS) {
         EXPECT_LE((unsigned int)3, response.size());
-        std::vector<uint8_t> command = SELECT_ISD;
-        std::vector<uint8_t> transmitResponse;
-        se_->transmit(command, [&transmitResponse](std::vector<uint8_t> res) {
-            transmitResponse.resize(res.size());
-            for (size_t i = 0; i < res.size(); i++) {
-                transmitResponse[i] = res[i];
-            }
-        });
-        EXPECT_LE((unsigned int)3, transmitResponse.size());
-        EXPECT_EQ(0x90, transmitResponse[transmitResponse.size() - 2]);
-        EXPECT_EQ(0x00, transmitResponse[transmitResponse.size() - 1]);
         return;
     }
     EXPECT_EQ(SecureElementStatus::UNSUPPORTED_OPERATION, statusReturned);
@@ -221,7 +199,7 @@
  * Close Channel
  */
 TEST_F(SecureElementHidlTest, openCloseLogicalChannel) {
-    std::vector<uint8_t> aid = CRS_AID;
+    std::vector<uint8_t> aid = ANDROID_TEST_AID;
     SecureElementStatus statusReturned;
     LogicalChannelResponse response;
     se_->openLogicalChannel(
@@ -238,7 +216,7 @@
             }
         });
     EXPECT_EQ(SecureElementStatus::SUCCESS, statusReturned);
-    EXPECT_LE((unsigned int)3, response.selectResponse.size());
+    EXPECT_LE((unsigned int)2, response.selectResponse.size());
     EXPECT_LE(1, response.channelNumber);
     EXPECT_EQ(SecureElementStatus::SUCCESS, se_->closeChannel(response.channelNumber));
 }
diff --git a/wifi/1.2/IWifiStaIface.hal b/wifi/1.2/IWifiStaIface.hal
index be4e537..3a7f777 100644
--- a/wifi/1.2/IWifiStaIface.hal
+++ b/wifi/1.2/IWifiStaIface.hal
@@ -17,6 +17,7 @@
 package android.hardware.wifi@1.2;
 
 import @1.0::WifiStatus;
+import @1.0::MacAddress;
 import @1.0::IWifiStaIface;
 
 /**
@@ -51,4 +52,17 @@
      * @see installApfPacketFilter()
      */
     readApfPacketFilterData() generates (WifiStatus status, vec<uint8_t> data);
+
+    /**
+     * Changes the MAC address of the Sta Interface to the given
+     * MAC address.
+     *
+     * @param mac MAC address to change into.
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    setMacAddress(MacAddress mac) generates (WifiStatus status);
 };
diff --git a/wifi/1.2/default/wifi_sta_iface.cpp b/wifi/1.2/default/wifi_sta_iface.cpp
index ab99daa..daa5610 100644
--- a/wifi/1.2/default/wifi_sta_iface.cpp
+++ b/wifi/1.2/default/wifi_sta_iface.cpp
@@ -241,6 +241,13 @@
                            hidl_status_cb);
 }
 
+Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
+                                         setMacAddress_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setMacAddressInternal, hidl_status_cb,
+                           mac);
+}
+
 std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
     return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
 }
@@ -594,6 +601,26 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
 }
 
+WifiStatus WifiStaIface::setMacAddressInternal(
+    const std::array<uint8_t, 6>& mac) {
+    if (!iface_tool_.SetWifiUpState(false)) {
+        LOG(ERROR) << "SetWifiUpState(false) failed.";
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+
+    if (!iface_tool_.SetMacAddress(ifname_.c_str(), mac)) {
+        LOG(ERROR) << "SetMacAddress failed.";
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+
+    if (!iface_tool_.SetWifiUpState(true)) {
+        LOG(ERROR) << "SetWifiUpState(true) failed.";
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    LOG(DEBUG) << "Successfully SetMacAddress.";
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace wifi
diff --git a/wifi/1.2/default/wifi_sta_iface.h b/wifi/1.2/default/wifi_sta_iface.h
index a212888..71cd17d 100644
--- a/wifi/1.2/default/wifi_sta_iface.h
+++ b/wifi/1.2/default/wifi_sta_iface.h
@@ -21,6 +21,8 @@
 #include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
 #include <android/hardware/wifi/1.2/IWifiStaIface.h>
 
+#include <wifi_system/interface_tool.h>
+
 #include "hidl_callback_util.h"
 #include "wifi_legacy_hal.h"
 
@@ -103,6 +105,8 @@
         getDebugTxPacketFates_cb hidl_status_cb) override;
     Return<void> getDebugRxPacketFates(
         getDebugRxPacketFates_cb hidl_status_cb) override;
+    Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
+                               setMacAddress_cb hidl_status_cb) override;
 
    private:
     // Corresponding worker functions for the HIDL methods.
@@ -146,12 +150,14 @@
     getDebugTxPacketFatesInternal();
     std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
     getDebugRxPacketFatesInternal();
+    WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
 
     std::string ifname_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     bool is_valid_;
     hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback>
         event_cb_handler_;
+    wifi_system::InterfaceTool iface_tool_;
 
     DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
 };
diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp
index d85d42e..918e4a4 100644
--- a/wifi/1.2/vts/functional/Android.bp
+++ b/wifi/1.2/vts/functional/Android.bp
@@ -20,6 +20,7 @@
     srcs: [
         "VtsHalWifiV1_2TargetTest.cpp",
         "wifi_chip_hidl_test.cpp",
+        "wifi_sta_iface_hidl_test.cpp",
     ],
     static_libs: [
         "VtsHalWifiV1_0TargetTestUtil",
diff --git a/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp
new file mode 100644
index 0000000..fd4a671
--- /dev/null
+++ b/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.2/IWifiStaIface.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::wifi::V1_2::IWifiStaIface;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+
+/**
+ * Fixture to use for all STA Iface HIDL interface tests.
+ */
+class WifiStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        wifi_sta_iface_ = IWifiStaIface::castFrom(getWifiStaIface());
+        ASSERT_NE(nullptr, wifi_sta_iface_.get());
+    }
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+    sp<IWifiStaIface> wifi_sta_iface_;
+};
+
+/*
+ * SetMacAddress:
+ * Ensures that calls to set MAC address will return a success status
+ * code.
+ */
+TEST_F(WifiStaIfaceHidlTest, SetMacAddress) {
+    const android::hardware::hidl_array<uint8_t, 6> kMac{
+        std::array<uint8_t, 6>{{0x12, 0x22, 0x33, 0x52, 0x10, 0x41}}};
+    EXPECT_EQ(WifiStatusCode::SUCCESS,
+              HIDL_INVOKE(wifi_sta_iface_, setMacAddress, kMac).code);
+}