Merge changes from topic "radio_mode_cbs_hidl"

* changes:
  wifi(implementation): Invoke radio mode change callbacks
  wifi(implementation): Conversion functions for radio mode change
  wifi(implementation): WifiLegacyHal interface for radio mode change
  wifi(interface): Add callbacks for indicating radio mode changes
diff --git a/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h b/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h
index 81d92c2..a96d06e 100644
--- a/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h
+++ b/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h
@@ -20,6 +20,7 @@
 #include <functional>
 #include <list>
 
+#include <VtsHalHidlTargetTestEnvBase.h>
 #include <gtest/gtest.h>
 
 namespace android {
@@ -33,13 +34,13 @@
  * Avoid destroying static objects after main return.
  * Post main return destruction leads to incorrect gtest timing measurements as
  * well as harder debuging if anything goes wrong during destruction. */
-class Environment : public ::testing::Environment {
+class Environment : public ::testing::VtsHalHidlTargetTestEnvBase {
    public:
     using TearDownFunc = std::function<void()>;
     void registerTearDown(TearDownFunc&& tearDown) { tearDowns.push_back(std::move(tearDown)); }
 
    private:
-    void TearDown() override {
+    void HidlTearDown() override {
         // Call the tear downs in reverse order of insertion
         for (auto& tearDown : tearDowns) {
             tearDown();
diff --git a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
index 6c09da7..bb1d26f 100644
--- a/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/2.0/vts/functional/AudioPrimaryHidlHalTest.cpp
@@ -88,8 +88,13 @@
 
 using namespace ::android::hardware::audio::common::test::utility;
 
+class AudioHidlTestEnvironment : public ::Environment {
+   public:
+    virtual void registerTestServices() override { registerTestService<IDevicesFactory>(); }
+};
+
 // Instance to register global tearDown
-static Environment* environment;
+static AudioHidlTestEnvironment* environment;
 
 class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
    protected:
@@ -109,7 +114,8 @@
 
         if (devicesFactory == nullptr) {
             environment->registerTearDown([] { devicesFactory.clear(); });
-            devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>();
+            devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>(
+                environment->getServiceName<IDevicesFactory>("default"));
         }
         ASSERT_TRUE(devicesFactory != nullptr);
     }
@@ -1265,9 +1271,10 @@
 //////////////////////////////////////////////////////////////////////////////
 
 int main(int argc, char** argv) {
-    environment = new Environment;
+    environment = new AudioHidlTestEnvironment;
     ::testing::AddGlobalTestEnvironment(environment);
     ::testing::InitGoogleTest(&argc, argv);
+    environment->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     return status;
 }
diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp
index ffe012e..a0d20f3 100644
--- a/automotive/vehicle/2.0/Android.bp
+++ b/automotive/vehicle/2.0/Android.bp
@@ -56,6 +56,7 @@
         "VehiclePropertyChangeMode",
         "VehiclePropertyGroup",
         "VehiclePropertyOperation",
+        "VehiclePropertyStatus",
         "VehiclePropertyType",
         "VehicleRadioConstants",
         "VehicleTurnSignal",
@@ -66,6 +67,7 @@
         "VmsMessageWithLayerAndPublisherIdIntegerValuesIndex",
         "VmsMessageWithLayerIntegerValuesIndex",
         "VmsOfferingMessageIntegerValuesIndex",
+        "VmsPublisherInformationIntegerValuesIndex",
         "VmsSubscriptionsStateIntegerValuesIndex",
         "Wheel",
     ],
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
index 8e9089d..6086c01 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/SubscriptionManager.h
@@ -49,7 +49,7 @@
     }
 
     void addOrUpdateSubscription(const SubscribeOptions &opts);
-    bool isSubscribed(int32_t propId, int32_t areaId, SubscribeFlags flags);
+    bool isSubscribed(int32_t propId, SubscribeFlags flags);
     std::vector<int32_t> getSubscribedProperties() const;
 
 private:
@@ -87,8 +87,7 @@
     /**
      * Constructs SubscriptionManager
      *
-     * @param onPropertyUnsubscribed - this callback function will be called when there are no
-     *                                    more client subscribed to particular property.
+     * @param onPropertyUnsubscribed - called when no more clients are subscribed to the property.
      */
     SubscriptionManager(const OnPropertyUnsubscribed& onPropertyUnsubscribed)
             : mOnPropertyUnsubscribed(onPropertyUnsubscribed),
@@ -115,9 +114,7 @@
             const std::vector<recyclable_ptr<VehiclePropValue>>& propValues,
             SubscribeFlags flags) const;
 
-    std::list<sp<HalClient>> getSubscribedClients(int32_t propId,
-                                                  int32_t area,
-                                                  SubscribeFlags flags) const;
+    std::list<sp<HalClient>> getSubscribedClients(int32_t propId, SubscribeFlags flags) const;
     /**
      * If there are no clients subscribed to given properties than callback function provided
      * in the constructor will be called.
@@ -125,10 +122,9 @@
     void unsubscribe(ClientId clientId, int32_t propId);
 private:
     std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId,
-                                                        int32_t area,
                                                         SubscribeFlags flags) const;
 
-    bool updateHalEventSubscriptionLocked(const SubscribeOptions &opts, SubscribeOptions* out);
+    bool updateHalEventSubscriptionLocked(const SubscribeOptions& opts, SubscribeOptions* out);
 
     void addClientToPropMapLocked(int32_t propId, const sp<HalClient>& client);
 
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHal.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHal.h
index 8203a1e..fd28483 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHal.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleHal.h
@@ -48,17 +48,14 @@
 
     /**
      * Subscribe to HAL property events. This method might be called multiple
-     * times for the same vehicle property to update subscribed areas or sample
-     * rate.
+     * times for the same vehicle property to update sample rate.
      *
      * @param property to subscribe
-     * @param areas a bitwise vehicle areas or 0 for all supported areas
      * @param sampleRate sample rate in Hz for properties that support sample
      *                   rate, e.g. for properties with
      *                   VehiclePropertyChangeMode::CONTINUOUS
      */
     virtual StatusCode subscribe(int32_t property,
-                                 int32_t areas,
                                  float sampleRate) = 0;
 
     /**
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
index 05c649b..359bb6d 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h
@@ -191,9 +191,8 @@
     VehiclePropValuePool& operator=(VehiclePropValuePool&) = delete;
 private:
     bool isDisposable(VehiclePropertyType type, size_t vecSize) const {
-        return vecSize > mMaxRecyclableVectorSize ||
-               VehiclePropertyType::STRING == type ||
-               VehiclePropertyType::COMPLEX == type;
+        return vecSize > mMaxRecyclableVectorSize || VehiclePropertyType::STRING == type ||
+               VehiclePropertyType::MIXED == type;
     }
 
     RecyclableType obtainDisposable(VehiclePropertyType valueType,
diff --git a/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp b/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
index 74f0a5f..a7d5f50 100644
--- a/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/SubscriptionManager.cpp
@@ -34,23 +34,12 @@
 bool mergeSubscribeOptions(const SubscribeOptions &oldOpts,
                            const SubscribeOptions &newOpts,
                            SubscribeOptions *outResult) {
-
-    int32_t updatedAreas = oldOpts.vehicleAreas;
-    if (updatedAreas != kAllSupportedAreas) {
-        updatedAreas = newOpts.vehicleAreas != kAllSupportedAreas
-            ? updatedAreas | newOpts.vehicleAreas
-            : kAllSupportedAreas;
-    }
-
     float updatedRate = std::max(oldOpts.sampleRate, newOpts.sampleRate);
     SubscribeFlags updatedFlags = SubscribeFlags(oldOpts.flags | newOpts.flags);
 
-    bool updated = updatedRate > oldOpts.sampleRate
-                   || updatedAreas != oldOpts.vehicleAreas
-                   || updatedFlags != oldOpts.flags;
+    bool updated = (updatedRate > oldOpts.sampleRate) || (updatedFlags != oldOpts.flags);
     if (updated) {
         *outResult = oldOpts;
-        outResult->vehicleAreas = updatedAreas;
         outResult->sampleRate = updatedRate;
         outResult->flags = updatedFlags;
     }
@@ -75,15 +64,13 @@
 }
 
 bool HalClient::isSubscribed(int32_t propId,
-                             int32_t areaId,
                              SubscribeFlags flags) {
     auto it = mSubscriptions.find(propId);
     if (it == mSubscriptions.end()) {
         return false;
     }
     const SubscribeOptions& opts = it->second;
-    bool res = (opts.flags & flags)
-           && (opts.vehicleAreas == 0 || areaId == 0 || opts.vehicleAreas & areaId);
+    bool res = (opts.flags & flags);
     return res;
 }
 
@@ -139,8 +126,7 @@
         MuxGuard g(mLock);
         for (const auto& propValue: propValues) {
             VehiclePropValue* v = propValue.get();
-            auto clients = getSubscribedClientsLocked(
-                v->prop, v->areaId, flags);
+            auto clients = getSubscribedClientsLocked(v->prop, flags);
             for (const auto& client : clients) {
                 clientValuesMap[client].push_back(v);
             }
@@ -158,21 +144,21 @@
     return clientValues;
 }
 
-std::list<sp<HalClient>> SubscriptionManager::getSubscribedClients(
-    int32_t propId, int32_t area, SubscribeFlags flags) const {
+std::list<sp<HalClient>> SubscriptionManager::getSubscribedClients(int32_t propId,
+                                                                   SubscribeFlags flags) const {
     MuxGuard g(mLock);
-    return getSubscribedClientsLocked(propId, area, flags);
+    return getSubscribedClientsLocked(propId, flags);
 }
 
 std::list<sp<HalClient>> SubscriptionManager::getSubscribedClientsLocked(
-        int32_t propId, int32_t area, SubscribeFlags flags) const {
+    int32_t propId, SubscribeFlags flags) const {
     std::list<sp<HalClient>> subscribedClients;
 
     sp<HalClientVector> propClients = getClientsForPropertyLocked(propId);
     if (propClients.get() != nullptr) {
         for (size_t i = 0; i < propClients->size(); i++) {
             const auto& client = propClients->itemAt(i);
-            if (client->isSubscribed(propId, area, flags)) {
+            if (client->isSubscribed(propId, flags)) {
                 subscribedClients.push_back(client);
             }
         }
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index ae543bb..1918421 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -142,15 +142,6 @@
             return StatusCode::INVALID_ARG;
         }
 
-        int32_t areas = isGlobalProp(prop) ? 0 : ops.vehicleAreas;
-        if (areas != 0 && ((areas & config->supportedAreas) != areas)) {
-            ALOGE("Failed to subscribe property 0x%x. Requested areas 0x%x are "
-                  "out of supported range of 0x%x", prop, ops.vehicleAreas,
-                  config->supportedAreas);
-            return StatusCode::INVALID_ARG;
-        }
-
-        ops.vehicleAreas = areas;
         ops.sampleRate = checkSampleRate(*config, ops.sampleRate);
     }
 
@@ -164,7 +155,7 @@
     }
 
     for (auto opt : updatedOptions) {
-        mHal->subscribe(opt.propId, opt.vehicleAreas, opt.sampleRate);
+        mHal->subscribe(opt.propId, opt.sampleRate);
     }
 
     return StatusCode::OK;
@@ -224,8 +215,8 @@
 void VehicleHalManager::onHalPropertySetError(StatusCode errorCode,
                                               int32_t property,
                                               int32_t areaId) {
-    const auto& clients = mSubscriptionManager.getSubscribedClients(
-            property, 0, SubscribeFlags::HAL_EVENT);
+    const auto& clients =
+        mSubscriptionManager.getSubscribedClients(property, SubscribeFlags::HAL_EVENT);
 
     for (auto client : clients) {
         client->getCallback()->onPropertySetError(errorCode, property, areaId);
@@ -326,8 +317,7 @@
 }
 
 void VehicleHalManager::handlePropertySetEvent(const VehiclePropValue& value) {
-    auto clients = mSubscriptionManager.getSubscribedClients(
-            value.prop, value.areaId, SubscribeFlags::SET_CALL);
+    auto clients = mSubscriptionManager.getSubscribedClients(value.prop, SubscribeFlags::SET_CALL);
     for (auto client : clients) {
         client->getCallback()->onPropertySet(value);
     }
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp b/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp
index ac1245a..3f98a94 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp
@@ -82,7 +82,7 @@
 }
 
 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainComplex() {
-    return obtain(VehiclePropertyType::COMPLEX);
+    return obtain(VehiclePropertyType::MIXED);
 }
 
 VehiclePropValuePool::RecyclableType VehiclePropValuePool::obtainRecylable(
@@ -138,18 +138,14 @@
 }
 
 bool VehiclePropValuePool::InternalPool::check(VehiclePropValue::RawValue* v) {
-    return check(&v->int32Values,
-                 (VehiclePropertyType::INT32 == mPropType
-                  || VehiclePropertyType::INT32_VEC == mPropType
-                  || VehiclePropertyType::BOOLEAN == mPropType))
-           && check(&v->floatValues,
-                    (VehiclePropertyType::FLOAT == mPropType
-                     || VehiclePropertyType::FLOAT_VEC == mPropType))
-           && check(&v->int64Values,
-                    VehiclePropertyType::INT64 == mPropType)
-           && check(&v->bytes,
-                    VehiclePropertyType::BYTES == mPropType)
-           && v->stringValue.size() == 0;
+    return check(&v->int32Values, (VehiclePropertyType::INT32 == mPropType ||
+                                   VehiclePropertyType::INT32_VEC == mPropType ||
+                                   VehiclePropertyType::BOOLEAN == mPropType)) &&
+           check(&v->floatValues, (VehiclePropertyType::FLOAT == mPropType ||
+                                   VehiclePropertyType::FLOAT_VEC == mPropType)) &&
+           check(&v->int64Values, (VehiclePropertyType::INT64 == mPropType ||
+                                   VehiclePropertyType::INT64_VEC == mPropType)) &&
+           check(&v->bytes, VehiclePropertyType::BYTES == mPropType) && v->stringValue.size() == 0;
 }
 
 VehiclePropValue* VehiclePropValuePool::InternalPool::createObject() {
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp b/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
index 9146fa1..34a6380 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp
@@ -42,13 +42,14 @@
             val->value.floatValues.resize(vecSize);
             break;
         case VehiclePropertyType::INT64:
+        case VehiclePropertyType::INT64_VEC:
             val->value.int64Values.resize(vecSize);
             break;
         case VehiclePropertyType::BYTES:
             val->value.bytes.resize(vecSize);
             break;
         case VehiclePropertyType::STRING:
-        case VehiclePropertyType::COMPLEX:
+        case VehiclePropertyType::MIXED:
             break; // Valid, but nothing to do.
         default:
             ALOGE("createVehiclePropValue: unknown type: %d", type);
@@ -68,6 +69,7 @@
         case VehiclePropertyType::FLOAT_VEC:
             return value.floatValues.size();
         case VehiclePropertyType::INT64:
+        case VehiclePropertyType::INT64_VEC:
             return value.int64Values.size();
         case VehiclePropertyType::BYTES:
             return value.bytes.size();
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 71601a0..18e8c40 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -54,10 +54,8 @@
  *   floatValues[1] - dispersion defines min and max range relative to initial value
  *   floatValues[2] - increment, with every timer tick the value will be incremented by this amount
  */
-const int32_t kGenerateFakeDataControllingProperty = 0x0666
-        | VehiclePropertyGroup::VENDOR
-        | VehicleArea::GLOBAL
-        | VehiclePropertyType::COMPLEX;
+const int32_t kGenerateFakeDataControllingProperty =
+    0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
 
 const int32_t kHvacPowerProperties[] = {
     toInt(VehicleProperty::HVAC_FAN_SPEED),
@@ -238,7 +236,8 @@
              .prop = toInt(VehicleProperty::HVAC_POWER_ON),
              .access = VehiclePropertyAccess::READ_WRITE,
              .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-             .supportedAreas = toInt(VehicleAreaZone::ROW_1),
+             .areaConfigs = {VehicleAreaConfig{
+                 .areaId = (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT)}},
              // TODO(bryaneyler): Ideally, this is generated dynamically from
              // kHvacPowerProperties.
              .configString = "0x12400500,0x12400501"  // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION
@@ -249,51 +248,52 @@
         .config = {.prop = toInt(VehicleProperty::HVAC_DEFROSTER),
                    .access = VehiclePropertyAccess::READ_WRITE,
                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                   .supportedAreas =
-                       VehicleAreaWindow::FRONT_WINDSHIELD | VehicleAreaWindow::REAR_WINDSHIELD},
+                   .areaConfigs =
+                       {VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD)},
+                        VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD)}}},
         .initialValue = {.int32Values = {0}}  // Will be used for all areas.
     },
 
     {.config = {.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .supportedAreas = toInt(VehicleAreaZone::ROW_1)},
+                .areaConfigs = {VehicleAreaConfig{
+                    .areaId = (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT)}}},
      .initialValue = {.int32Values = {1}}},
 
     {.config = {.prop = toInt(VehicleProperty::HVAC_AC_ON),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .supportedAreas = toInt(VehicleAreaZone::ROW_1)},
+                .areaConfigs = {VehicleAreaConfig{
+                    .areaId = (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT)}}},
      .initialValue = {.int32Values = {1}}},
 
     {.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_ON),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .supportedAreas = toInt(VehicleAreaZone::ROW_1)},
+                .areaConfigs = {VehicleAreaConfig{
+                    .areaId = (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT)}}},
      .initialValue = {.int32Values = {1}}},
 
     {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .supportedAreas = toInt(VehicleAreaZone::ROW_1),
-                .areaConfigs = {VehicleAreaConfig{.areaId = toInt(VehicleAreaZone::ROW_1),
-                                                  .minInt32Value = 1,
-                                                  .maxInt32Value = 7}}},
+                .areaConfigs = {VehicleAreaConfig{
+                    .areaId = (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
+                    .minInt32Value = 1,
+                    .maxInt32Value = 7}}},
      .initialValue = {.int32Values = {3}}},
 
-    {.config =
-         {
-             .prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
-             .access = VehiclePropertyAccess::READ_WRITE,
-             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-             .supportedAreas = toInt(VehicleAreaZone::ROW_1),
-         },
+    {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
+                .access = VehiclePropertyAccess::READ_WRITE,
+                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                .areaConfigs = {VehicleAreaConfig{
+                    .areaId = (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT)}}},
      .initialValue = {.int32Values = {toInt(VehicleHvacFanDirection::FACE)}}},
 
     {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                 .access = VehiclePropertyAccess::READ_WRITE,
                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .supportedAreas = VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT,
                 .areaConfigs = {VehicleAreaConfig{
                                     .areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
                                     .minFloatValue = 16,
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 6bc0522..16d2b0b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -138,8 +138,9 @@
             return status;
         }
     } else if (mHvacPowerProps.count(propValue.prop)) {
-        auto hvacPowerOn = mPropStore->readValueOrNull(toInt(VehicleProperty::HVAC_POWER_ON),
-                                                      toInt(VehicleAreaZone::ROW_1));
+        auto hvacPowerOn = mPropStore->readValueOrNull(
+            toInt(VehicleProperty::HVAC_POWER_ON),
+            (VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT));
 
         if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1
                 && hvacPowerOn->value.int32Values[0] == 0) {
@@ -177,7 +178,7 @@
 void EmulatedVehicleHal::onCreate() {
     for (auto& it : kVehicleProperties) {
         VehiclePropConfig cfg = it.config;
-        int32_t supportedAreas = cfg.supportedAreas;
+        int32_t numAreas = cfg.areaConfigs.size();
 
         if (isDiagnosticProperty(cfg)) {
             // do not write an initial empty value for the diagnostic properties
@@ -185,22 +186,26 @@
             continue;
         }
 
-        //  A global property will have supportedAreas = 0
+        // A global property will have only a single area
         if (isGlobalProp(cfg.prop)) {
-            supportedAreas = 0;
+            numAreas = 1;
         }
 
-        // This loop is a do-while so it executes at least once to handle global properties
-        do {
-            int32_t curArea = supportedAreas;
-            supportedAreas &= supportedAreas - 1;  // Clear the right-most bit of supportedAreas.
-            curArea ^= supportedAreas;  // Set curArea to the previously cleared bit.
+        for (int i = 0; i < numAreas; i++) {
+            int32_t curArea;
+
+            if (isGlobalProp(cfg.prop)) {
+                curArea = 0;
+            } else {
+                curArea = cfg.areaConfigs[i].areaId;
+            }
 
             // Create a separate instance for each individual zone
             VehiclePropValue prop = {
                 .prop = cfg.prop,
                 .areaId = curArea,
             };
+
             if (it.initialAreaValues.size() > 0) {
                 auto valueForAreaIt = it.initialAreaValues.find(curArea);
                 if (valueForAreaIt != it.initialAreaValues.end()) {
@@ -213,8 +218,7 @@
                 prop.value = it.initialValue;
             }
             mPropStore->writeValue(prop);
-
-        } while (supportedAreas != 0);
+        }
     }
     initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
     initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
@@ -246,8 +250,7 @@
     }
 }
 
-StatusCode EmulatedVehicleHal::subscribe(int32_t property, int32_t,
-                                        float sampleRate) {
+StatusCode EmulatedVehicleHal::subscribe(int32_t property, float sampleRate) {
     ALOGI("%s propId: 0x%x, sampleRate: %f", __func__, property, sampleRate);
 
     if (isContinuousProperty(property)) {
@@ -389,7 +392,7 @@
 }
 
 void EmulatedVehicleHal::initObd2LiveFrame(const VehiclePropConfig& propConfig) {
-    auto liveObd2Frame = createVehiclePropValue(VehiclePropertyType::COMPLEX, 0);
+    auto liveObd2Frame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
     auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
                                             static_cast<size_t>(propConfig.configArray[1]));
     sensorStore->fillPropValue("", liveObd2Frame.get());
@@ -406,7 +409,7 @@
                                                   "P0102"
                                                   "P0123"};
     for (auto&& dtc : sampleDtcs) {
-        auto freezeFrame = createVehiclePropValue(VehiclePropertyType::COMPLEX, 0);
+        auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
         sensorStore->fillPropValue(dtc, freezeFrame.get());
         freezeFrame->prop = OBD2_FREEZE_FRAME;
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index 99d7edb..62fc126 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -53,7 +53,7 @@
     VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
                             StatusCode* outStatus) override;
     StatusCode set(const VehiclePropValue& propValue) override;
-    StatusCode subscribe(int32_t property, int32_t areas, float sampleRate) override;
+    StatusCode subscribe(int32_t property, float sampleRate) override;
     StatusCode unsubscribe(int32_t property) override;
 
     //  Methods from EmulatedVehicleHalIface
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
index 38cb743..fca8e9e 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
@@ -234,10 +234,6 @@
     protoCfg->set_change_mode(toInt(cfg.changeMode));
     protoCfg->set_value_type(toInt(getPropType(cfg.prop)));
 
-    if (!isGlobalProp(cfg.prop)) {
-        protoCfg->set_supported_areas(cfg.supportedAreas);
-    }
-
     for (auto& configElement : cfg.configArray) {
         protoCfg->add_config_array(configElement);
     }
@@ -251,9 +247,10 @@
         case VehiclePropertyType::STRING:
         case VehiclePropertyType::BOOLEAN:
         case VehiclePropertyType::INT32_VEC:
+        case VehiclePropertyType::INT64_VEC:
         case VehiclePropertyType::FLOAT_VEC:
         case VehiclePropertyType::BYTES:
-        case VehiclePropertyType::COMPLEX:
+        case VehiclePropertyType::MIXED:
             // Do nothing.  These types don't have min/max values
             break;
         case VehiclePropertyType::INT64:
diff --git a/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp b/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
index 5688dd6..4865e9e 100644
--- a/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/SubscriptionManager_test.cpp
@@ -51,11 +51,7 @@
     }
 
     hidl_vec<SubscribeOptions> subscrToProp1 = {
-        SubscribeOptions {
-            .propId = PROP1,
-            .vehicleAreas = toInt(VehicleAreaZone::ROW_1_LEFT),
-            .flags = SubscribeFlags::HAL_EVENT
-        },
+        SubscribeOptions{.propId = PROP1, .flags = SubscribeFlags::HAL_EVENT},
     };
 
     hidl_vec<SubscribeOptions> subscrToProp2 = {
@@ -66,15 +62,8 @@
     };
 
     hidl_vec<SubscribeOptions> subscrToProp1and2 = {
-        SubscribeOptions {
-            .propId = PROP1,
-            .vehicleAreas = toInt(VehicleAreaZone::ROW_1_LEFT),
-            .flags = SubscribeFlags::HAL_EVENT
-        },
-        SubscribeOptions {
-            .propId = PROP2,
-            .flags = SubscribeFlags::HAL_EVENT
-        },
+        SubscribeOptions{.propId = PROP1, .flags = SubscribeFlags::HAL_EVENT},
+        SubscribeOptions{.propId = PROP2, .flags = SubscribeFlags::HAL_EVENT},
     };
 
     static std::list<sp<IVehicleCallback>> extractCallbacks(
@@ -87,14 +76,11 @@
     }
 
     std::list<sp<HalClient>> clientsToProp1() {
-        return manager.getSubscribedClients(PROP1,
-                                            toInt(VehicleAreaZone::ROW_1_LEFT),
-                                            SubscribeFlags::DEFAULT);
+        return manager.getSubscribedClients(PROP1, SubscribeFlags::DEFAULT);
     }
 
     std::list<sp<HalClient>> clientsToProp2() {
-        return manager.getSubscribedClients(PROP2, 0,
-                                            SubscribeFlags::DEFAULT);
+        return manager.getSubscribedClients(PROP2, SubscribeFlags::DEFAULT);
     }
 
     void onPropertyUnsubscribed(int propertyId) {
@@ -126,7 +112,6 @@
 
     auto clients = manager.getSubscribedClients(
             PROP1,
-            toInt(VehicleAreaZone::ROW_1_LEFT),
             SubscribeFlags::HAL_EVENT);
 
     ASSERT_ALL_EXISTS({cb1, cb2}, extractCallbacks(clients));
@@ -137,24 +122,14 @@
     ASSERT_EQ(StatusCode::OK,
               manager.addOrUpdateSubscription(1, cb1, subscrToProp1, &updatedOptions));
 
-    // Wrong zone
-    auto clients = manager.getSubscribedClients(
-            PROP1,
-            toInt(VehicleAreaZone::ROW_2_LEFT),
-            SubscribeFlags::HAL_EVENT);
-    ASSERT_TRUE(clients.empty());
-
     // Wrong prop
-    clients = manager.getSubscribedClients(
-            toInt(VehicleProperty::AP_POWER_BOOTUP_REASON),
-            toInt(VehicleAreaZone::ROW_1_LEFT),
-            SubscribeFlags::HAL_EVENT);
+    auto clients = manager.getSubscribedClients(toInt(VehicleProperty::AP_POWER_BOOTUP_REASON),
+                                                SubscribeFlags::HAL_EVENT);
     ASSERT_TRUE(clients.empty());
 
     // Wrong flag
     clients = manager.getSubscribedClients(
             PROP1,
-            toInt(VehicleAreaZone::ROW_1_LEFT),
             SubscribeFlags::SET_CALL);
     ASSERT_TRUE(clients.empty());
 }
@@ -166,7 +141,6 @@
 
     auto clients = manager.getSubscribedClients(
             PROP1,
-            toInt(VehicleAreaZone::ROW_1_LEFT),
             SubscribeFlags::DEFAULT);
     ASSERT_EQ((size_t) 1, clients.size());
     ASSERT_EQ(cb1, clients.front()->getCallback());
@@ -176,18 +150,15 @@
     ASSERT_EQ(StatusCode::OK, manager.addOrUpdateSubscription(1, cb1, {
         SubscribeOptions {
                 .propId = PROP1,
-                .vehicleAreas = toInt(VehicleAreaZone::ROW_2),
                 .flags = SubscribeFlags::DEFAULT
             }
         }, &updatedOptions));
 
     clients = manager.getSubscribedClients(PROP1,
-                                           toInt(VehicleAreaZone::ROW_1_LEFT),
                                            SubscribeFlags::DEFAULT);
     ASSERT_ALL_EXISTS({cb1}, extractCallbacks(clients));
 
     clients = manager.getSubscribedClients(PROP1,
-                                           toInt(VehicleAreaZone::ROW_2),
                                            SubscribeFlags::DEFAULT);
     ASSERT_ALL_EXISTS({cb1}, extractCallbacks(clients));
 }
diff --git a/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp b/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
index 4864d5d..5b195db 100644
--- a/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/VehicleHalManager_test.cpp
@@ -106,7 +106,6 @@
     }
 
     StatusCode subscribe(int32_t /* property */,
-                         int32_t /* areas */,
                          float /* sampleRate */) override {
         return StatusCode::OK;
     }
@@ -286,6 +285,7 @@
 
     cb->reset();
     VehiclePropValue actualValue(*subscribedValue.get());
+    actualValue.status = VehiclePropertyStatus::AVAILABLE;
     hal->sendPropEvent(std::move(subscribedValue));
 
     ASSERT_TRUE(cb->waitForExpectedEvents(1)) << "Events received: "
diff --git a/automotive/vehicle/2.0/default/tests/VehicleHalTestUtils.h b/automotive/vehicle/2.0/default/tests/VehicleHalTestUtils.h
index 2a06417..3cabcf2 100644
--- a/automotive/vehicle/2.0/default/tests/VehicleHalTestUtils.h
+++ b/automotive/vehicle/2.0/default/tests/VehicleHalTestUtils.h
@@ -29,10 +29,8 @@
 namespace vehicle {
 namespace V2_0 {
 
-constexpr int32_t kCustomComplexProperty = 0xbeef
-        | VehiclePropertyGroup::VENDOR
-        | VehiclePropertyType::COMPLEX
-        | VehicleArea::GLOBAL;
+constexpr int32_t kCustomComplexProperty =
+    0xbeef | VehiclePropertyGroup::VENDOR | VehiclePropertyType::MIXED | VehicleArea::GLOBAL;
 
 const VehiclePropConfig kVehicleProperties[] = {
     {
@@ -46,8 +44,6 @@
         .prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
         .access = VehiclePropertyAccess::READ_WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas = static_cast<int32_t>(
-            VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
         .areaConfigs = {
             VehicleAreaConfig {
                 .areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
@@ -66,8 +62,6 @@
         .prop = toInt(VehicleProperty::HVAC_SEAT_TEMPERATURE),
         .access = VehiclePropertyAccess::WRITE,
         .changeMode = VehiclePropertyChangeMode::ON_SET,
-        .supportedAreas = static_cast<int32_t>(
-            VehicleAreaZone::ROW_1_LEFT | VehicleAreaZone::ROW_1_RIGHT),
         .areaConfigs = {
             VehicleAreaConfig {
                 .areaId = toInt(VehicleAreaZone::ROW_1_LEFT),
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 7e42781..f673d1a 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -27,6 +27,7 @@
     INT32          = 0x00400000,
     INT32_VEC      = 0x00410000,
     INT64          = 0x00500000,
+    INT64_VEC      = 0x00510000,
     FLOAT          = 0x00600000,
     FLOAT_VEC      = 0x00610000,
     BYTES          = 0x00700000,
@@ -35,7 +36,7 @@
      * Any combination of scalar or vector types. The exact format must be
      * provided in the description of the property.
      */
-    COMPLEX        = 0x00e00000,
+    MIXED          = 0x00e00000,
 
     MASK           = 0x00ff0000
 };
@@ -315,7 +316,7 @@
     WHEEL_TICK = (
       0x0306
       | VehiclePropertyGroup:SYSTEM
-      | VehiclePropertyType:COMPLEX
+      | VehiclePropertyType:MIXED
       | VehicleArea:GLOBAL),
 
 
@@ -1673,7 +1674,7 @@
     /**
      * Vehicle Maps Service (VMS) message
      *
-     * This property uses COMPLEX data to communicate vms messages.
+     * This property uses MIXED data to communicate vms messages.
      *
      * Its contents are to be interpreted as follows:
      * the indices defined in VmsMessageIntegerValuesIndex are to be used to
@@ -1689,7 +1690,7 @@
     VEHICLE_MAP_SERVICE = (
         0x0C00
         | VehiclePropertyGroup:SYSTEM
-        | VehiclePropertyType:COMPLEX
+        | VehiclePropertyType:MIXED
         | VehicleArea:GLOBAL),
 
     /**
@@ -1736,7 +1737,7 @@
     OBD2_LIVE_FRAME = (
       0x0D00
       | VehiclePropertyGroup:SYSTEM
-      | VehiclePropertyType:COMPLEX
+      | VehiclePropertyType:MIXED
       | VehicleArea:GLOBAL),
 
     /**
@@ -1766,7 +1767,7 @@
     OBD2_FREEZE_FRAME = (
       0x0D01
       | VehiclePropertyGroup:SYSTEM
-      | VehiclePropertyType:COMPLEX
+      | VehiclePropertyType:MIXED
       | VehicleArea:GLOBAL),
 
     /**
@@ -1787,7 +1788,7 @@
     OBD2_FREEZE_FRAME_INFO = (
       0x0D02
       | VehiclePropertyGroup:SYSTEM
-      | VehiclePropertyType:COMPLEX
+      | VehiclePropertyType:MIXED
       | VehicleArea:GLOBAL),
 
     /**
@@ -1813,7 +1814,7 @@
     OBD2_FREEZE_FRAME_CLEAR = (
       0x0D03
       | VehiclePropertyGroup:SYSTEM
-      | VehiclePropertyType:COMPLEX
+      | VehiclePropertyType:MIXED
       | VehicleArea:GLOBAL),
 };
 
@@ -2169,6 +2170,21 @@
 };
 
 /**
+ * Property status is a dynamic value that may change based on the vehicle state.
+ */
+enum VehiclePropertyStatus : int32_t {
+    /** Property is available and behaving normally */
+    AVAILABLE   = 0x00,
+    /**
+     * Property is not available, for read and/or write.  This is a transient state, as the
+     *  property is expected to be available at a later time.
+     */
+    UNAVAILABLE = 0x01,
+    /** There is an error with this property. */
+    ERROR       = 0x02,
+};
+
+/**
  * Car states.
  *
  * The driving states determine what features of the UI will be accessible.
@@ -2212,20 +2228,15 @@
   ROW_1_LEFT = 0x00000001,
   ROW_1_CENTER = 0x00000002,
   ROW_1_RIGHT = 0x00000004,
-  ROW_1 = 0x00000008,
   ROW_2_LEFT = 0x00000010,
   ROW_2_CENTER = 0x00000020,
   ROW_2_RIGHT = 0x00000040,
-  ROW_2 = 0x00000080,
   ROW_3_LEFT = 0x00000100,
   ROW_3_CENTER = 0x00000200,
   ROW_3_RIGHT = 0x00000400,
-  ROW_3 = 0x00000800,
   ROW_4_LEFT = 0x00001000,
   ROW_4_CENTER = 0x00002000,
   ROW_4_RIGHT = 0x00004000,
-  ROW_4 = 0x00008000,
-  WHOLE_CABIN = 0x80000000,
 };
 
 /**
@@ -2313,13 +2324,6 @@
     VehiclePropertyChangeMode changeMode;
 
     /**
-     * Some of the properties may have associated areas (for example, some hvac
-     * properties are associated with VehicleAreaZone), in these
-     * cases the config may contain an ORed value for the associated areas.
-     */
-    int32_t supportedAreas;
-
-    /**
      * Contains per-area configuration.
      */
     vec<VehicleAreaConfig> areaConfigs;
@@ -2372,6 +2376,9 @@
      */
     int32_t areaId;
 
+    /** Status of the property */
+    VehiclePropertyStatus status;
+
     /**
      * Contains value for a single property. Depending on property data type of
      * this property (VehiclePropetyType) one field of this structure must be filled in.
@@ -2484,12 +2491,6 @@
     int32_t propId;
 
     /**
-     * Area ids - this must be a bit mask of areas to subscribe or 0 to subscribe
-     * to all areas.
-     */
-    int32_t vehicleAreas;
-
-    /**
      * Sample rate in Hz.
      *
      * Must be provided for properties with
@@ -2894,9 +2895,42 @@
      * A message from the VMS service to the subscribers or from the publishers to the VMS service
      * with a serialized VMS data packet as defined in the VMS protocol.
      *
-     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
      */
     DATA = 12,
+
+    /**
+     * A request from the publishers to the VMS service to get a Publisher ID for a serialized VMS
+     * provider description packet as defined in the VMS protocol.
+     *
+     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     */
+    PUBLISHER_ID_REQUEST = 13,
+
+    /**
+     * A response from the VMS service to the publisher that contains a provider description packet
+     * and the publisher ID assigned to it.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_ID_RESPONSE = 14,
+
+    /**
+     * A request from the subscribers to the VMS service to get information for a Publisher ID.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_INFORMATION_REQUEST = 15,
+
+    /**
+     * A response from the VMS service to the subscribers that contains a provider description packet
+     * and the publisher ID assigned to it.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_INFORMATION_RESPONSE = 16,
+
+    LAST_VMS_MESSAGE_TYPE = PUBLISHER_INFORMATION_RESPONSE,
 };
 
 /**
@@ -2924,7 +2958,8 @@
 
 /*
  * A VMS message with a layer and publisher ID is sent as part of a
- * VmsMessageType.SUBSCRIBE_TO_PUBLISHER and VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER messages.
+ * VmsMessageType.SUBSCRIBE_TO_PUBLISHER, VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER messages and
+ * VmsMessageType.DATA .
  */
 enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex : VmsMessageWithLayerIntegerValuesIndex {
     PUBLISHER_ID = 4,
@@ -2993,3 +3028,11 @@
     LAYERS_START = 3,
 };
 
+/*
+ * Publishers send the VMS service their information and assigned in response a publisher ID.
+ * Subscribers can request the publisher information for a publisher ID they received in other messages.
+ */
+enum VmsPublisherInformationIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
+    PUBLISHER_ID = 1,
+};
+
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 31b4739..ae275ae 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -738,8 +738,14 @@
 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
         RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
-    Status status = initStatus();
     CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
+Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata) {
+    Status status = initStatus();
     const camera_metadata_t *rawRequest;
     if (status == Status::OK) {
         ATRACE_BEGIN("camera3->construct_default_request_settings");
@@ -761,15 +767,14 @@
                         defaultBoost, 1);
                 const camera_metadata_t *metaBuffer =
                         mOverridenRequest.getAndLock();
-                convertToHidl(metaBuffer, &outMetadata);
+                convertToHidl(metaBuffer, outMetadata);
                 mOverridenRequest.unlock(metaBuffer);
             } else {
-                convertToHidl(rawRequest, &outMetadata);
+                convertToHidl(rawRequest, outMetadata);
             }
         }
     }
-    _hidl_cb(status, outMetadata);
-    return Void();
+    return status;
 }
 
 /**
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 0048ef4..dd73b39 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -112,7 +112,9 @@
     Return<Status> flush();
     Return<void> close();
 
-    //Helper methods
+    // Helper methods
+    Status constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata);
+
     bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration,
             camera3_stream_configuration_t *stream_list /*out*/,
             hidl_vec<camera3_stream_t*> *streams /*out*/);
diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp
index 822cf69..b3757c0 100644
--- a/camera/device/3.4/Android.bp
+++ b/camera/device/3.4/Android.bp
@@ -22,6 +22,7 @@
         "HalStream",
         "HalStreamConfiguration",
         "PhysicalCameraSetting",
+        "RequestTemplate",
         "Stream",
         "StreamConfiguration",
     ],
diff --git a/camera/device/3.4/ICameraDeviceSession.hal b/camera/device/3.4/ICameraDeviceSession.hal
index 4ce749d..7afcf94 100644
--- a/camera/device/3.4/ICameraDeviceSession.hal
+++ b/camera/device/3.4/ICameraDeviceSession.hal
@@ -17,6 +17,7 @@
 package android.hardware.camera.device@3.4;
 
 import android.hardware.camera.common@1.0::Status;
+import @3.2::CameraMetadata;
 import @3.3::ICameraDeviceSession;
 import @3.3::HalStreamConfiguration;
 import @3.2::BufferCache;
@@ -30,6 +31,43 @@
 interface ICameraDeviceSession extends @3.3::ICameraDeviceSession {
 
     /**
+     * constructDefaultRequestSettings_3_4:
+     *
+     * Create capture settings for standard camera use cases. Supports the
+     * new template enums added in @3.4.
+     *
+     * The device must return a settings buffer that is configured to meet the
+     * requested use case, which must be one of the CAMERA3_TEMPLATE_*
+     * enums. All request control fields must be included.
+     *
+     * Performance requirements:
+     *
+     * This must be a non-blocking call. The HAL should return from this call
+     * in 1ms, and must return from this call in 5ms.
+     *
+     * Return values:
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *         On a successful construction of default settings.
+     *     INTERNAL_ERROR:
+     *         An unexpected internal error occurred, and the default settings
+     *         are not available.
+     *     ILLEGAL_ARGUMENT:
+     *         The camera HAL does not support the input template type
+     *     CAMERA_DISCONNECTED:
+     *         An external camera device has been disconnected, and is no longer
+     *         available. This camera device interface is now stale, and a new
+     *         instance must be acquired if the device is reconnected. All
+     *         subsequent calls on this interface must return
+     *         CAMERA_DISCONNECTED.
+     * @return requestTemplate The default capture request settings for the requested
+     *     use case, or an empty metadata structure if status is not OK.
+     *
+     */
+    constructDefaultRequestSettings_3_4(RequestTemplate type) generates
+            (Status status, @3.2::CameraMetadata requestTemplate);
+
+    /**
      * configureStreams_3_4:
      *
      * Identical to @3.3::ICameraDeviceSession.configureStreams, except that:
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index c8d33eb..d054788 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -40,6 +40,14 @@
 CameraDeviceSession::~CameraDeviceSession() {
 }
 
+Return<void> CameraDeviceSession::constructDefaultRequestSettings_3_4(
+        RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
+    V3_2::CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
 Return<void> CameraDeviceSession::configureStreams_3_4(
         const StreamConfiguration& requestedConfiguration,
         ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb)  {
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 9589782..507f092 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -178,33 +178,53 @@
 }
 
 Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings(
+        V3_2::RequestTemplate type,
+        V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
+    V3_2::CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw(
+            static_cast<RequestTemplate>(type), &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
+Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings_3_4(
         RequestTemplate type,
-        ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
+        ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
+    V3_2::CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw(type, &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
+Status ExternalCameraDeviceSession::constructDefaultRequestSettingsRaw(RequestTemplate type,
+        V3_2::CameraMetadata *outMetadata) {
     CameraMetadata emptyMd;
     Status status = initStatus();
     if (status != Status::OK) {
-        _hidl_cb(status, emptyMd);
-        return Void();
+        return status;
     }
 
     switch (type) {
         case RequestTemplate::PREVIEW:
         case RequestTemplate::STILL_CAPTURE:
         case RequestTemplate::VIDEO_RECORD:
-        case RequestTemplate::VIDEO_SNAPSHOT:
-            _hidl_cb(Status::OK, mDefaultRequests[static_cast<int>(type)]);
+        case RequestTemplate::VIDEO_SNAPSHOT: {
+            *outMetadata = mDefaultRequests[type];
             break;
+        }
         case RequestTemplate::MANUAL:
         case RequestTemplate::ZERO_SHUTTER_LAG:
-            // Don't support MANUAL or ZSL template
-            _hidl_cb(Status::ILLEGAL_ARGUMENT, emptyMd);
+        case RequestTemplate::MOTION_TRACKING_PREVIEW:
+        case RequestTemplate::MOTION_TRACKING_BEST:
+            // Don't support MANUAL, ZSL, MOTION_TRACKING_* templates
+            status = Status::ILLEGAL_ARGUMENT;
             break;
         default:
             ALOGE("%s: unknown request template type %d", __FUNCTION__, static_cast<int>(type));
-            _hidl_cb(Status::ILLEGAL_ARGUMENT, emptyMd);
+            status = Status::ILLEGAL_ARGUMENT;
             break;
     }
-    return Void();
+    return status;
 }
 
 Return<void> ExternalCameraDeviceSession::configureStreams(
@@ -1767,21 +1787,21 @@
     const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
     UPDATE(md, ANDROID_CONTROL_MODE, &controlMode, 1);
 
-    for (int type = static_cast<int>(RequestTemplate::PREVIEW);
-            type <= static_cast<int>(RequestTemplate::VIDEO_SNAPSHOT); type++) {
+    auto requestTemplates = hidl_enum_iterator<RequestTemplate>();
+    for (RequestTemplate type : requestTemplates) {
         ::android::hardware::camera::common::V1_0::helper::CameraMetadata mdCopy = md;
         uint8_t intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
         switch (type) {
-            case static_cast<int>(RequestTemplate::PREVIEW):
+            case RequestTemplate::PREVIEW:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
                 break;
-            case static_cast<int>(RequestTemplate::STILL_CAPTURE):
+            case RequestTemplate::STILL_CAPTURE:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
                 break;
-            case static_cast<int>(RequestTemplate::VIDEO_RECORD):
+            case RequestTemplate::VIDEO_RECORD:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
                 break;
-            case static_cast<int>(RequestTemplate::VIDEO_SNAPSHOT):
+            case RequestTemplate::VIDEO_SNAPSHOT:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
                 break;
             default:
@@ -1987,4 +2007,3 @@
 }  // namespace camera
 }  // namespace hardware
 }  // namespace android
-
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 fbde083..913bd78 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
@@ -73,6 +73,9 @@
     // Methods from v3.3 and earlier will trampoline to inherited implementation
 
     // New methods for v3.4
+    Return<void> constructDefaultRequestSettings_3_4(
+            RequestTemplate type,
+            ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
 
     Return<void> configureStreams_3_4(
             const StreamConfiguration& requestedConfiguration,
@@ -139,6 +142,12 @@
             return mParent->close();
         }
 
+        virtual Return<void> constructDefaultRequestSettings_3_4(
+                RequestTemplate type,
+                ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings_3_4(type, _hidl_cb);
+        }
+
         virtual Return<void> configureStreams_3_3(
                 const V3_2::StreamConfiguration& requestedConfiguration,
                 configureStreams_3_3_cb _hidl_cb) override {
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index 404dfe0..d8a17f6 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -51,7 +51,7 @@
 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
 using ::android::hardware::camera::device::V3_2::MsgType;
 using ::android::hardware::camera::device::V3_2::NotifyMsg;
-using ::android::hardware::camera::device::V3_2::RequestTemplate;
+using ::android::hardware::camera::device::V3_4::RequestTemplate;
 using ::android::hardware::camera::device::V3_2::Stream;
 using ::android::hardware::camera::device::V3_4::StreamConfiguration;
 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
@@ -172,7 +172,11 @@
     // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow
 
     Return<void> constructDefaultRequestSettings(
-            RequestTemplate,
+            V3_2::RequestTemplate,
+            ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
+
+    Return<void> constructDefaultRequestSettings_3_4(
+            RequestTemplate type,
             ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
 
     Return<void> configureStreams(
@@ -227,6 +231,9 @@
         std::vector<HalStreamBuffer> buffers;
     };
 
+    Status constructDefaultRequestSettingsRaw(RequestTemplate type,
+            V3_2::CameraMetadata *outMetadata);
+
     static std::vector<SupportedV4L2Format> sortFormats(
             const std::vector<SupportedV4L2Format>&);
     static CroppingType initCroppingType(const std::vector<SupportedV4L2Format>&);
@@ -363,7 +370,7 @@
     // Protect against invokeProcessCaptureResultCallback()
     Mutex mProcessCaptureResultLock;
 
-    std::unordered_map<int, CameraMetadata> mDefaultRequests;
+    std::unordered_map<RequestTemplate, CameraMetadata> mDefaultRequests;
     /* End of members not changed after initialize() */
 
 private:
@@ -408,6 +415,12 @@
             return mParent->close();
         }
 
+        virtual Return<void> constructDefaultRequestSettings_3_4(
+                RequestTemplate type,
+                ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings_3_4(type, _hidl_cb);
+        }
+
         virtual Return<void> configureStreams_3_3(
                 const V3_2::StreamConfiguration& requestedConfiguration,
                 configureStreams_3_3_cb _hidl_cb) override {
diff --git a/camera/device/3.4/types.hal b/camera/device/3.4/types.hal
index 77e855f..429db3e 100644
--- a/camera/device/3.4/types.hal
+++ b/camera/device/3.4/types.hal
@@ -16,7 +16,7 @@
 
 package android.hardware.camera.device@3.4;
 
-import @3.2::types;
+import @3.2::RequestTemplate;
 import @3.2::StreamConfigurationMode;
 import @3.2::Stream;
 import @3.3::HalStream;
@@ -62,6 +62,36 @@
 };
 
 /**
+ * New request templates, extending the @3.2 RequestTemplate
+ */
+enum RequestTemplate : @3.2::RequestTemplate {
+    /**
+     * A template for selecting camera parameters that match TEMPLATE_PREVIEW as closely as
+     * possible while improving the camera output for motion tracking use cases.
+     *
+     * This template is best used by applications that are frequently switching between motion
+     * tracking use cases and regular still capture use cases, to minimize the IQ changes
+     * when swapping use cases.
+     *
+     * This template is guaranteed to be supported on camera devices that support the
+     * REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING capability.
+     */
+    MOTION_TRACKING_PREVIEW = 7,
+
+    /**
+     * A template for selecting camera parameters that maximize the quality of camera output for
+     * motion tracking use cases.
+     *
+     * This template is best used by applications dedicated to motion tracking applications,
+     * which aren't concerned about fast switches between motion tracking and other use cases.
+     *
+     * This template is guaranteed to be supported on camera devices that support the
+     * REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING capability.
+     */
+    MOTION_TRACKING_BEST = 8,
+};
+
+/**
  * StreamConfiguration:
  *
  * Identical to @3.2::StreamConfiguration, except that it contains session
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 2a01480..1c86f11 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -16,123 +16,78 @@
 
 LOCAL_PATH := $(call my-dir)
 
+BUILD_FRAMEWORK_COMPATIBILITY_MATRIX := $(LOCAL_PATH)/compatibility_matrix.mk
+
+# Clear potential input variables to BUILD_FRAMEWORK_COMPATIBILITY_MATRIX
+LOCAL_ADD_VBMETA_VERSION :=
+LOCAL_ASSEMBLE_VINTF_ENV_VARS :=
+LOCAL_ASSEMBLE_VINTF_FLAGS :=
+LOCAL_KERNEL_VERSIONS :=
+LOCAL_GEN_FILE_DEPENDENCIES :=
+
 # Install all compatibility_matrix.*.xml to /system/etc/vintf
 
+
 include $(CLEAR_VARS)
-LOCAL_MODULE := framework_compatibility_matrix.legacy.xml
 LOCAL_MODULE_STEM := compatibility_matrix.legacy.xml
 LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
-include $(BUILD_PREBUILT)
+LOCAL_KERNEL_VERSIONS := 3.18.0 4.4.0 4.9.0
+include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := framework_compatibility_matrix.1.xml
 LOCAL_MODULE_STEM := compatibility_matrix.1.xml
 LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
-include $(BUILD_PREBUILT)
+LOCAL_KERNEL_VERSIONS := 3.18.0 4.4.0 4.9.0
+include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := framework_compatibility_matrix.2.xml
 LOCAL_MODULE_STEM := compatibility_matrix.2.xml
 LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
-include $(BUILD_PREBUILT)
+LOCAL_KERNEL_VERSIONS := 3.18.0 4.4.0 4.9.0
+include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
+
+# TODO(b/72409164): STOPSHIP: update kernel version requirements
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := framework_compatibility_matrix.current.xml
 LOCAL_MODULE_STEM := compatibility_matrix.current.xml
 LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
-include $(BUILD_PREBUILT)
+LOCAL_KERNEL_VERSIONS := 4.4.0 4.9.0
+include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
 
-# Framework Compatibility Matrix without HALs
+# Framework Compatibility Matrix (common to all FCM versions)
+
 include $(CLEAR_VARS)
-LOCAL_MODULE        := framework_compatibility_matrix.empty.xml
-LOCAL_MODULE_STEM   := compatibility_matrix.empty.xml
-LOCAL_MODULE_CLASS  := ETC
-LOCAL_MODULE_PATH   := $(TARGET_OUT)/etc/vintf
+LOCAL_MODULE_STEM := compatibility_matrix.empty.xml
+LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
+LOCAL_ADD_VBMETA_VERSION := true
+LOCAL_ASSEMBLE_VINTF_ENV_VARS := \
+	POLICYVERS \
+	BOARD_SEPOLICY_VERS
 
-GEN := $(local-generated-sources-dir)/$(LOCAL_MODULE_STEM)
-
-$(GEN): PRIVATE_FLAGS :=
-
-ifeq (true,$(BOARD_AVB_ENABLE))
-$(GEN): $(AVBTOOL)
-# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
-# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
-# is a file, here.
-$(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
-# Use deferred assignment (=) instead of immediate assignment (:=).
-# Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
-$(GEN): FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
-                           --print_required_libavb_version \
-                           $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
-                           $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
-else
-$(GEN): FRAMEWORK_VBMETA_VERSION := 0.0
-endif
-
-# Specify kernel versions that the current framework supports. These versions,
-# along with kernel configurations, are written to the framework compatibility
-# matrix.
-$(GEN): KERNEL_VERSIONS := 3.18 4.4 4.9
-
-# Specify the location of android-base*.cfg files.
-$(GEN): KERNEL_CONFIG_DATA := kernel/configs
-
-$(GEN): $(foreach version,$(KERNEL_VERSIONS),\
-	$(wildcard $(KERNEL_CONFIG_DATA)/android-$(version)/android-base*.cfg))
-$(GEN): PRIVATE_FLAGS += $(foreach version,$(KERNEL_VERSIONS),\
-	--kernel=$(version):$(call normalize-path-list,\
-		$(wildcard $(KERNEL_CONFIG_DATA)/android-$(version)/android-base*.cfg)))
-
-$(GEN): $(LOCAL_PATH)/compatibility_matrix.empty.xml $(HOST_OUT_EXECUTABLES)/assemble_vintf
-	POLICYVERS=$(POLICYVERS) \
-		BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \
-		FRAMEWORK_VBMETA_VERSION=$(FRAMEWORK_VBMETA_VERSION) \
-		$(HOST_OUT_EXECUTABLES)/assemble_vintf \
-		-i $< -o $@ $(PRIVATE_FLAGS)
-LOCAL_PREBUILT_MODULE_FILE := $(GEN)
-include $(BUILD_PREBUILT)
+include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
 
 # Framework Compatibility Matrix
-include $(CLEAR_VARS)
-LOCAL_MODULE        := framework_compatibility_matrix.xml
-LOCAL_MODULE_STEM   := compatibility_matrix.xml
-LOCAL_MODULE_CLASS  := ETC
-LOCAL_MODULE_PATH   := $(TARGET_OUT)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.xml
+LOCAL_MODULE_STEM := compatibility_matrix.xml
+LOCAL_MODULE_PATH := $(TARGET_OUT)
 LOCAL_REQUIRED_MODULES := \
     framework_compatibility_matrix.legacy.xml \
     framework_compatibility_matrix.1.xml \
     framework_compatibility_matrix.2.xml \
     framework_compatibility_matrix.current.xml \
     framework_compatibility_matrix.empty.xml
-
-GEN := $(local-generated-sources-dir)/compatibility_matrix.xml
-
-$(GEN): PRIVATE_FLAGS :=
+LOCAL_GENERATED_SOURCES := $(call module-installed-files,$(LOCAL_REQUIRED_MODULES))
 
 ifdef BUILT_VENDOR_MANIFEST
-$(GEN): $(BUILT_VENDOR_MANIFEST)
-$(GEN): PRIVATE_FLAGS += -c "$(BUILT_VENDOR_MANIFEST)"
+LOCAL_GEN_FILE_DEPENDENCIES += $(BUILT_VENDOR_MANIFEST)
+LOCAL_ASSEMBLE_VINTF_FLAGS += -c "$(BUILT_VENDOR_MANIFEST)"
 endif
 
-MATRIX_SRC_FILES := $(call module-installed-files,$(LOCAL_REQUIRED_MODULES))
-$(GEN): PRIVATE_MATRIX_SRC_FILES := $(MATRIX_SRC_FILES)
-$(GEN): $(MATRIX_SRC_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf
-	PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
-		$(HOST_OUT_EXECUTABLES)/assemble_vintf \
-		-i $(call normalize-path-list,$(PRIVATE_MATRIX_SRC_FILES)) \
-		-o $@ $(PRIVATE_FLAGS)
+LOCAL_ASSEMBLE_VINTF_ENV_VARS := PRODUCT_ENFORCE_VINTF_MANIFEST
 
-MATRIX_SRC_FILES :=
-
-LOCAL_PREBUILT_MODULE_FILE := $(GEN)
-include $(BUILD_PREBUILT)
+include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX)
 BUILT_SYSTEM_COMPATIBILITY_MATRIX := $(LOCAL_BUILT_MODULE)
+
+BUILD_FRAMEWORK_COMPATIBILITY_MATRIX :=
diff --git a/compatibility_matrices/compatibility_matrix.mk b/compatibility_matrices/compatibility_matrix.mk
new file mode 100644
index 0000000..14c60ab
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.mk
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+###########################################################
+## Remove minor revision from a kernel version. For example,
+## 3.18.0 becomes 3.18.
+## $(1): kernel version
+###########################################################
+define remove-minor-revision
+$(strip $(subst $(space),.,$(wordlist 1,2,$(subst .,$(space),$(strip $(1))))))
+endef
+
+# $(warning $(call remove-minor-revision,3.18.0))
+
+ifndef LOCAL_MODULE_STEM
+$(error LOCAL_MODULE_STEM must be defined.)
+endif
+
+LOCAL_MODULE := framework_$(LOCAL_MODULE_STEM)
+LOCAL_MODULE_CLASS := ETC
+
+ifndef LOCAL_MODULE_PATH
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
+endif
+
+GEN := $(local-generated-sources-dir)/$(LOCAL_MODULE_STEM)
+
+$(GEN): PRIVATE_ENV_VARS := $(LOCAL_ASSEMBLE_VINTF_ENV_VARS)
+$(GEN): PRIVATE_FLAGS := $(LOCAL_ASSEMBLE_VINTF_FLAGS)
+
+$(GEN): $(LOCAL_GEN_FILE_DEPENDENCIES)
+
+ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION)))
+ifeq (true,$(BOARD_AVB_ENABLE))
+$(GEN): $(AVBTOOL)
+# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
+# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
+# is a file, here.
+$(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
+# Use deferred assignment (=) instead of immediate assignment (:=).
+# Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
+$(GEN): FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
+                           --print_required_libavb_version \
+                           $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
+                           $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
+else
+$(GEN): FRAMEWORK_VBMETA_VERSION := 0.0
+endif # BOARD_AVB_ENABLE
+$(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION
+endif # LOCAL_ADD_VBMETA_VERSION
+
+ifneq (,$(strip $(LOCAL_KERNEL_VERSIONS)))
+$(GEN): PRIVATE_KERNEL_CONFIG_DATA := kernel/configs
+$(GEN): PRIVATE_KERNEL_VERSIONS := $(LOCAL_KERNEL_VERSIONS)
+$(GEN): $(foreach version,$(PRIVATE_KERNEL_VERSIONS),\
+    $(wildcard $(PRIVATE_KERNEL_CONFIG_DATA)/android-$(call remove-minor-revision,$(version))/android-base*.cfg))
+$(GEN): PRIVATE_FLAGS += $(foreach version,$(PRIVATE_KERNEL_VERSIONS),\
+    --kernel=$(version):$(call normalize-path-list,\
+        $(wildcard $(PRIVATE_KERNEL_CONFIG_DATA)/android-$(call remove-minor-revision,$(version))/android-base*.cfg)))
+endif
+
+my_matrix_src_files := \
+	$(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) \
+	$(LOCAL_GENERATED_SOURCES)
+
+$(GEN): PRIVATE_SRC_FILES := $(my_matrix_src_files)
+$(GEN): $(my_matrix_src_files) $(HOST_OUT_EXECUTABLES)/assemble_vintf
+	$(foreach varname,$(PRIVATE_ENV_VARS),$(varname)=$($(varname))) \
+		$(HOST_OUT_EXECUTABLES)/assemble_vintf \
+		-i $(call normalize-path-list,$(PRIVATE_SRC_FILES)) \
+		-o $@ \
+		$(PRIVATE_FLAGS)
+
+LOCAL_PREBUILT_MODULE_FILE := $(GEN)
+LOCAL_SRC_FILES :=
+LOCAL_GENERATED_SOURCES :=
+
+LOCAL_ADD_VBMETA_VERSION :=
+LOCAL_ASSEMBLE_VINTF_ENV_VARS :=
+LOCAL_ASSEMBLE_VINTF_FLAGS :=
+LOCAL_KERNEL_VERSIONS :=
+LOCAL_GEN_FILE_DEPENDENCIES :=
+my_matrix_src_files :=
+
+include $(BUILD_PREBUILT)
+
+remove-minor-revision :=
diff --git a/drm/1.0/default/DrmPlugin.cpp b/drm/1.0/default/DrmPlugin.cpp
index 1695ef7..809f694 100644
--- a/drm/1.0/default/DrmPlugin.cpp
+++ b/drm/1.0/default/DrmPlugin.cpp
@@ -93,6 +93,7 @@
                 requestType = KeyRequestType::RELEASE;
                 break;
             case android::DrmPlugin::kKeyRequestType_Unknown:
+            default:
                 requestType = KeyRequestType::UNKNOWN;
                 break;
             }
diff --git a/drm/1.1/Android.bp b/drm/1.1/Android.bp
index c895af6..ed8196e 100644
--- a/drm/1.1/Android.bp
+++ b/drm/1.1/Android.bp
@@ -18,6 +18,7 @@
     ],
     types: [
         "HdcpLevel",
+        "KeyRequestType",
         "SecurityLevel",
     ],
     gen_java: false,
diff --git a/drm/1.1/IDrmPlugin.hal b/drm/1.1/IDrmPlugin.hal
index 0660a43..c32d2b5 100644
--- a/drm/1.1/IDrmPlugin.hal
+++ b/drm/1.1/IDrmPlugin.hal
@@ -17,8 +17,12 @@
 
 import @1.0::IDrmPlugin;
 import @1.0::IDrmPluginListener;
+import @1.0::KeyedVector;
+import @1.0::KeyType;
 import @1.0::Status;
+import @1.1::DrmMetricGroup;
 import @1.1::HdcpLevel;
+import @1.1::KeyRequestType;
 import @1.1::SecurityLevel;
 
 /**
@@ -28,6 +32,59 @@
  */
 interface IDrmPlugin extends @1.0::IDrmPlugin {
     /**
+     * A key request/response exchange occurs between the app and a License
+     * Server to obtain the keys required to decrypt the content.
+     * getKeyRequest_1_1() is used to obtain an opaque key request blob that is
+     * delivered to the license server.
+     *
+     * getKeyRequest_1_1() only differs from getKeyRequest() in that additional
+     * values are returned in 1.1::KeyRequestType as compared to
+     * 1.0::KeyRequestType
+     *
+     * @param scope may be a sessionId or a keySetId, depending on the
+     *        specified keyType. When the keyType is OFFLINE or STREAMING,
+     *        scope should be set to the sessionId the keys will be provided
+     *        to. When the keyType is RELEASE, scope should be set to the
+     *        keySetId of the keys being released.
+     * @param initData container-specific data, its meaning is interpreted
+     *        based on the mime type provided in the mimeType parameter.
+     *        It could contain, for example, the content ID, key ID or
+     *        other data obtained from the content metadata that is
+     *        required to generate the key request. initData may be empty
+     *        when keyType is RELEASE.
+     * @param mimeType identifies the mime type of the content
+     * @param keyType specifies if the keys are to be used for streaming,
+     *        offline or a release
+     * @param optionalParameters included in the key request message to
+     *        allow a client application to provide additional message
+     *        parameters to the server.
+     * @return status the status of the call. The status must be OK or one of
+     *         the following errors: ERROR_DRM_SESSION_NOT_OPENED if the
+     *         session is not opened, ERROR_DRM_NOT_PROVISIONED if the device
+     *         requires provisioning before it can generate a key request,
+     *         ERROR_DRM_CANNOT_HANDLE if getKeyRequest is not supported
+     *         at the time of the call, BAD_VALUE if any parameters are
+     *         invalid or ERROR_DRM_INVALID_STATE if the HAL is in a
+     *         state where a key request cannot be generated.
+     * @return request if successful, the opaque key request blob is returned
+     * @return requestType indicates type information about the returned
+     *         request. The type may be one of INITIAL, RENEWAL, RELEASE,
+     *         NONE or UPDATE. An INITIAL request is the first key request
+     *         for a license. RENEWAL is a subsequent key request used to
+     *         refresh the keys in a license. RELEASE corresponds to a
+     *         keyType of RELEASE, which indicates keys are being released.
+     *         NONE indicates that no request is needed because the keys are
+     *         already loaded. UPDATE indicates that the keys need to be
+     *         refetched after the initial license request.
+     * @return defaultUrl the URL that the request may be sent to, if
+     *         provided by the drm HAL. The app may choose to override this URL.
+     */
+    getKeyRequest_1_1(vec<uint8_t> scope, vec<uint8_t> initData,
+            string mimeType, KeyType keyType, KeyedVector optionalParameters)
+        generates (Status status, vec<uint8_t> request,
+                KeyRequestType requestType, string defaultUrl);
+
+    /**
      * Return the currently negotiated and max supported HDCP levels.
      *
      * The current level is based on the display(s) the device is connected to.
@@ -106,4 +163,17 @@
      */
     setSecurityLevel(vec<uint8_t> sessionId, SecurityLevel level)
             generates(Status status);
+
+    /**
+     * Returns the plugin-specific metrics. Multiple metric groups may be
+     * returned in one call to getMetrics(). The scope and definition of the
+     * metrics is defined by the plugin.
+     *
+     * @return status the status of the call. The status must be OK or
+     *         ERROR_DRM_INVALID_STATE if the metrics are not available to be
+     *         returned.
+     * @return metric_groups the collection of metric groups provided by the
+     *         plugin.
+     */
+    getMetrics() generates (Status status, vec<DrmMetricGroup> metric_groups);
 };
diff --git a/drm/1.1/types.hal b/drm/1.1/types.hal
index 9447524..94a6e66 100644
--- a/drm/1.1/types.hal
+++ b/drm/1.1/types.hal
@@ -16,6 +16,105 @@
 
 package android.hardware.drm@1.1;
 
+import @1.0::KeyRequestType;
+
+/**
+ * This message contains plugin-specific metrics made available to the client.
+ * The message is used for making vendor-specific metrics available to an
+ * application. The framework is not consuming any of the information.
+ *
+ * Metrics are grouped in instances of DrmMetricGroup. Each group contains
+ * multiple instances of Metric.
+ *
+ * Example:
+ *
+ * Capture the timing information of a buffer copy event, "buf_copy", broken
+ * out by the "size" of the buffer.
+ *
+ * DrmMetricGroup {
+ *   metrics[0] {
+ *     name: "buf_copy"
+ *     attributes[0] {
+ *       name: "size"
+ *       type: INT64_TYPE
+ *       int64Value: 1024
+ *     }
+ *     values[0] {
+ *       componentName: "operation_count"
+ *       type: INT64_TYPE
+ *       int64Value: 75
+ *     }
+ *     values[1] {
+ *       component_name: "average_time_seconds"
+ *       type: DOUBLE_TYPE
+ *       doubleValue: 0.00000042
+ *     }
+ *   }
+ * }
+ */
+struct DrmMetricGroup {
+    /**
+     * Used to discriminate the type of value being stored in the structs
+     * below.
+     */
+    enum ValueType : uint8_t {
+        INT64_TYPE,
+        DOUBLE_TYPE,
+        STRING_TYPE,
+    };
+
+    /**
+     * A detail about the metric being captured. The fields of an Attribute
+     * are opaque to the framework.
+     */
+    struct Attribute {
+        string name;
+        /**
+         * The type field indicates which of the following values is used.
+         */
+        ValueType type;
+        int64_t int64Value;
+        double doubleValue;
+        string stringValue;
+    };
+
+    /**
+     * A value of the metric. A metric may have multiple values. The
+     * component name may be left empty if there is only supposed to be
+     * one value for the given metric. The fields of the Value are
+     * opaque to the framework.
+     */
+    struct Value {
+        string componentName;
+        /**
+         * The type field indicates which of the following values is used.
+         */
+        ValueType type;
+        int64_t int64Value;
+        double doubleValue;
+        string stringValue;
+    };
+
+    /**
+     * The metric being captured. A metric must have a name and at least one
+     * value. A metric may have 0 or more attributes. The fields of a Metric
+     * are opaque to the framework.
+     */
+    struct Metric {
+        string name;
+        vec<Attribute> attributes;
+        // A Metric may have one or more values. Multiple values are useful
+        // for capturing different aspects of the same metric. E.g. capture
+        // the min, max, average, count, and stdev of a particular metric.
+        vec<Value> values;
+    };
+
+    /**
+     * The list of metrics to be captured.
+     */
+    vec<Metric> metrics;
+};
+
 /**
  * HDCP specifications are defined by Digital Content Protection LLC (DCP).
  *   "HDCP Specification Rev. 2.2 Interface Independent Adaptation"
@@ -58,6 +157,23 @@
     HDCP_NO_OUTPUT
 };
 
+/**
+ * KeyRequestTypes (in addition to those from 1.0) which allow an app
+ * to determine the type of a key request returned from getKeyRequest.
+ */
+enum KeyRequestType : @1.0::KeyRequestType {
+    /**
+     * Keys are already loaded. No key request is needed.
+     */
+    NONE,
+
+    /**
+     * Keys have previously been loaded. An additional (non-renewal) license
+     * request is needed.
+     */
+    UPDATE,
+};
+
 enum SecurityLevel : uint32_t {
     /**
      * Unable to determine the security level
@@ -93,3 +209,4 @@
      */
     HW_SECURE_ALL,
 };
+
diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp
index 72ef282..c319d80 100644
--- a/graphics/common/1.1/Android.bp
+++ b/graphics/common/1.1/Android.bp
@@ -15,6 +15,7 @@
     ],
     types: [
         "BufferUsage",
+        "Dataspace",
         "PixelFormat",
     ],
     gen_java: true,
diff --git a/graphics/common/1.1/types.hal b/graphics/common/1.1/types.hal
index 135f6e3..b917d5e 100644
--- a/graphics/common/1.1/types.hal
+++ b/graphics/common/1.1/types.hal
@@ -18,6 +18,7 @@
 
 import @1.0::PixelFormat;
 import @1.0::BufferUsage;
+import @1.0::Dataspace;
 
 /**
  * Pixel formats for graphics buffers.
@@ -77,6 +78,39 @@
      * defined by the dataspace.
      */
     STENCIL_8           = 0x35,
+
+    /**
+     * P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane
+     * followed immediately by a Wx(H/2) CbCr plane. Each sample is
+     * represented by a 16-bit little-endian value, with the lower 6 bits set
+     * to zero.
+     *
+     * This format assumes
+     * - an even height
+     * - a vertical stride equal to the height
+     *
+     *   stride_in_bytes = stride * 2
+     *   y_size = stride_in_bytes * height
+     *   cbcr_size = stride_in_bytes * (height / 2)
+     *   cb_offset = y_size
+     *   cr_offset = cb_offset + 2
+     *
+     * This format must be accepted by the allocator when used with the
+     * following usage flags:
+     *
+     *    - BufferUsage::VIDEO_*
+     *    - BufferUsage::CPU_*
+     *    - BufferUsage::GPU_TEXTURE
+     *
+     * The component values are unsigned normalized to the range [0, 1], whose
+     * interpretation is defined by the dataspace.
+     *
+     * This format is appropriate for 10bit video content.
+     *
+     * Buffers with this format must be locked with IMapper::lockYCbCr
+     * or with IMapper::lock.
+     */
+    YCBCR_P010          = 0x36,
 };
 
 /**
@@ -91,3 +125,19 @@
 
     /** bits 27 and 32-47 must be zero and are reserved for future versions */
 };
+
+@export(name="android_dataspace_v1_1_t", value_prefix="HAL_DATASPACE_",
+        export_parent="false")
+enum Dataspace : @1.0::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
+     */
+    BT2020_ITU = STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED,
+
+    BT2020_ITU_PQ = STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED,
+};
diff --git a/graphics/mapper/2.1/IMapper.hal b/graphics/mapper/2.1/IMapper.hal
index a23656d..6047e96 100644
--- a/graphics/mapper/2.1/IMapper.hal
+++ b/graphics/mapper/2.1/IMapper.hal
@@ -16,10 +16,47 @@
 
 package android.hardware.graphics.mapper@2.1;
 
-import android.hardware.graphics.mapper@2.0::Error;
-import android.hardware.graphics.mapper@2.0::IMapper;
+import android.hardware.graphics.common@1.1::BufferUsage;
+import android.hardware.graphics.common@1.1::PixelFormat;
+import @2.0::BufferDescriptor;
+import @2.0::Error;
+import @2.0::IMapper;
 
-interface IMapper extends android.hardware.graphics.mapper@2.0::IMapper {
+interface IMapper extends @2.0::IMapper {
+    /**
+     * This is the same as @2.0::IMapper::BufferDescriptorInfo except that it
+     * accepts @1.1::PixelFormat and @1.1::BufferUsage.
+     */
+    struct BufferDescriptorInfo {
+        /**
+         * The width specifies how many columns of pixels must be in the
+         * allocated buffer, but does not necessarily represent the offset in
+         * columns between the same column in adjacent rows. The rows may be
+         * padded.
+         */
+        uint32_t width;
+
+       /**
+        * The height specifies how many rows of pixels must be in the
+        * allocated buffer.
+        */
+        uint32_t height;
+
+       /**
+        * The number of image layers that must be in the allocated buffer.
+        */
+        uint32_t layerCount;
+
+        /** Buffer pixel format. */
+        PixelFormat format;
+
+        /**
+         * Buffer usage mask; valid flags can be found in the definition of
+         * BufferUsage.
+         */
+        bitfield<BufferUsage> usage;
+    };
+
     /**
      * Validate that the buffer can be safely accessed by a caller who assumes
      * the specified descriptorInfo and stride. This must at least validate
@@ -58,4 +95,30 @@
             generates (Error error,
                        uint32_t numFds,
                        uint32_t numInts);
+
+    /**
+     * This is the same as @2.0::IMapper::createDescriptor except that it
+     * accepts @2.1::IMapper::BufferDescriptorInfo.
+     *
+     * Creates a buffer descriptor. The descriptor can be used with IAllocator
+     * to allocate buffers.
+     *
+     * Since the buffer descriptor fully describes a buffer, any device
+     * dependent or device independent checks must be performed here whenever
+     * possible. Specifically, when layered buffers are not supported, this
+     * function must return UNSUPPORTED if layerCount is great than 1.
+     *
+     * @param descriptorInfo specifies the attributes of the descriptor.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_VALUE when any of the specified attributes is
+     *                            invalid or conflicting.
+     *                  NO_RESOURCES when the creation cannot be fullfilled at
+     *                               this time.
+     *                  UNSUPPORTED when any of the specified attributes is
+     *                              not supported.
+     * @return descriptor is the newly created buffer descriptor.
+     */
+    createDescriptor_2_1(BufferDescriptorInfo descriptorInfo)
+              generates (Error error,
+                         BufferDescriptor descriptor);
 };
diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
index 4067c8d..88b96ae 100644
--- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
+++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp
@@ -30,10 +30,27 @@
 namespace tests {
 namespace {
 
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
 using android::hardware::graphics::mapper::V2_0::Error;
 
-using android::hardware::graphics::common::V1_0::BufferUsage;
-using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::common::V1_1::BufferUsage;
+using android::hardware::graphics::common::V1_1::PixelFormat;
+
+// abuse VTS to check binary compatibility between BufferDescriptorInfos
+using OldBufferDescriptorInfo =
+    android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo;
+static_assert(sizeof(OldBufferDescriptorInfo) == sizeof(IMapper::BufferDescriptorInfo) &&
+                  offsetof(OldBufferDescriptorInfo, width) ==
+                      offsetof(IMapper::BufferDescriptorInfo, width) &&
+                  offsetof(OldBufferDescriptorInfo, height) ==
+                      offsetof(IMapper::BufferDescriptorInfo, height) &&
+                  offsetof(OldBufferDescriptorInfo, layerCount) ==
+                      offsetof(IMapper::BufferDescriptorInfo, layerCount) &&
+                  offsetof(OldBufferDescriptorInfo, format) ==
+                      offsetof(IMapper::BufferDescriptorInfo, format) &&
+                  offsetof(OldBufferDescriptorInfo, usage) ==
+                      offsetof(IMapper::BufferDescriptorInfo, usage),
+              "");
 
 class Gralloc : public V2_0::tests::Gralloc {
    public:
@@ -72,6 +89,32 @@
         });
     }
 
+    BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+        BufferDescriptor descriptor;
+        mMapper->createDescriptor_2_1(
+            descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+                ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
+                descriptor = tmpDescriptor;
+            });
+
+        return descriptor;
+    }
+
+    const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
+                                    bool import, uint32_t* outStride = nullptr) {
+        BufferDescriptor descriptor = createDescriptor(descriptorInfo);
+        if (::testing::Test::HasFatalFailure()) {
+            return nullptr;
+        }
+
+        auto buffers = V2_0::tests::Gralloc::allocate(descriptor, 1, import, outStride);
+        if (::testing::Test::HasFatalFailure()) {
+            return nullptr;
+        }
+
+        return buffers[0];
+    }
+
    private:
     void init() {
         mMapper = IMapper::castFrom(V2_0::tests::Gralloc::getMapper());
@@ -229,6 +272,24 @@
     native_handle_delete(rawBufferHandle);
 }
 
+/**
+ * Test IMapper::createDescriptor with valid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptor_2_1Basic) {
+    ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
+}
+
+/**
+ * Test IMapper::createDescriptor with invalid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) {
+    auto info = mDummyDescriptorInfo;
+    info.width = 0;
+    mGralloc->getMapper()->createDescriptor_2_1(info, [&](const auto& tmpError, const auto&) {
+        EXPECT_EQ(Error::BAD_VALUE, tmpError) << "createDescriptor did not fail with BAD_VALUE";
+    });
+}
+
 }  // namespace
 }  // namespace tests
 }  // namespace V2_1
@@ -238,7 +299,10 @@
 }  // namespace android
 
 int main(int argc, char** argv) {
+    using android::hardware::graphics::mapper::V2_0::tests::GraphicsMapperHidlEnvironment;
+    ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
+    GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
 
     int status = RUN_ALL_TESTS();
     LOG(INFO) << "Test result = " << status;
diff --git a/radio/1.2/Android.bp b/radio/1.2/Android.bp
index 56e4afd..f4ca1cf 100644
--- a/radio/1.2/Android.bp
+++ b/radio/1.2/Android.bp
@@ -20,6 +20,7 @@
     ],
     types: [
         "CardStatus",
+        "CellConnectionStatus",
         "CellIdentityCdma",
         "CellIdentityGsm",
         "CellIdentityLte",
@@ -31,9 +32,12 @@
         "CellInfoLte",
         "CellInfoWcdma",
         "IncrementalResultsPeriodicityRange",
+        "IndicationFilter",
+        "LinkCapacityEstimate",
         "MaxSearchTimeRange",
         "NetworkScanRequest",
         "NetworkScanResult",
+        "PhysicalChannelConfig",
         "RadioConst",
         "ScanIntervalRange",
     ],
diff --git a/radio/1.2/IRadio.hal b/radio/1.2/IRadio.hal
index 6ae78a0..babe86f 100644
--- a/radio/1.2/IRadio.hal
+++ b/radio/1.2/IRadio.hal
@@ -17,6 +17,7 @@
 package android.hardware.radio@1.2;
 
 import @1.1::IRadio;
+import @1.1::RadioAccessNetworks;
 
 /**
  * This interface is used by telephony and telecom to talk to cellular radio.
@@ -37,4 +38,72 @@
      * Response function is IRadioResponse.startNetworkScanResponse()
      */
     oneway startNetworkScan_1_2(int32_t serial, NetworkScanRequest request);
+
+    /**
+     * Sets the indication filter.
+     *
+     * Prevents the reporting of specified unsolicited indications from the radio. This is used
+     * for power saving in instances when those indications are not needed. If unset, defaults to
+     * @1.2::IndicationFilter:ALL.
+     *
+     * @param serial Serial number of request.
+     * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the
+     *        indications are enabled. See @1.2::IndicationFilter for the definition of each bit.
+     *
+     * Response callback is IRadioResponse.setIndicationFilterResponse()
+     */
+    oneway setIndicationFilter_1_2(int32_t serial, bitfield<IndicationFilter> indicationFilter);
+
+    /**
+     * Sets the signal strength reporting criteria.
+     *
+     * The resulting reporting criteria are the AND of all the supplied criteria.
+     *
+     * Note: Reporting criteria must be individually set for each RAN. If unset, reporting criteria
+     * for that RAN are implementation-defined.
+     *
+     * Response callback is IRadioResponse.setSignalStrengthReportingCriteriaResponse().
+     *
+     * @param serial Serial number of request.
+     * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0
+     *                     disables hysteresis.
+     * @param hysteresisDb An interval in dB defining the required magnitude change between reports.
+     *                     hysteresisDb must be smaller than the smallest threshold delta. An
+     *                     interval value of 0 disables hysteresis.
+     * @param thresholdsDbm A vector of trigger thresholds in dBm. A vector size of 0 disables the
+     *                      use of thresholds for reporting.
+     * @param ran The type of network for which to apply these thresholds.
+     */
+    oneway setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs,
+            int32_t hysteresisDb, vec<int32_t> thresholdsDbm, RadioAccessNetworks ran);
+
+    /**
+     * Sets the link capacity reporting criteria.
+     *
+     * The resulting reporting criteria are the AND of all the supplied criteria.
+     *
+     * Note: Reporting criteria must be individually set for each RAN. If unset, reporting criteria
+     * for that RAN are implementation-defined.
+     *
+     * Response callback is IRadioResponse.setLinkCapacityReportingCriteriaResponse().
+     *
+     * @param serial Serial number of request.
+     * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0
+     *                     disables hysteresis.
+     * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL
+     *                         reports. hysteresisDlKbps must be smaller than the smallest threshold
+     *                         delta. A value of 0 disables hysteresis.
+     * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL
+     *                         reports. hysteresisUlKbps must be smaller than the smallest threshold
+     *                         delta. A value of 0 disables hysteresis.
+     * @param thresholdsDownlinkKbps A vector of trigger thresholds in kbps for downlink reports. A
+     *                               vector size of 0 disables the use of DL thresholds for
+     *                               reporting.
+     * @param thresholdsUplinkKbps A vector of trigger thresholds in kbps for uplink reports. A
+     *                             vector size of 0 disables the use of UL thresholds for reporting.
+     * @param ran The type of network for which to apply these thresholds.
+     */
+    oneway setLinkCapacityReportingCriteria(int32_t serial, int32_t hysteresisMs,
+            int32_t hysteresisDlKbps, int32_t hysteresisUlKbps, vec<int32_t> thresholdsDownlinkKbps,
+            vec<int32_t> thresholdsUplinkKbps, RadioAccessNetworks ran);
 };
diff --git a/radio/1.2/IRadioIndication.hal b/radio/1.2/IRadioIndication.hal
index 22f655c..a124557 100644
--- a/radio/1.2/IRadioIndication.hal
+++ b/radio/1.2/IRadioIndication.hal
@@ -37,4 +37,29 @@
      * @param records Current cell information known to radio
      */
      oneway cellInfoList_1_2(RadioIndicationType type, vec<CellInfo> records);
+
+    /**
+     * Indicates current link capacity estimate.
+     *
+     * This replaces @1.0::IRadioIndication.lceData(). The framework must be able to handle
+     * either this function or @1.0::IRadioIndication.lceData(). Implementations supporting
+     * v1.2 must call this function instead of lceData().
+     *
+     * This indication is sent whenever the reporting criteria, as set by
+     * @1.2::IRadio.setLinkCapacityReportingCriteria, are met and the indication is not
+     * suppressed by @1.2::IRadio.setIndicationFilter_1_2().
+     *
+     * @param type Type of radio indication
+     * @param lce LinkCapacityEstimate information as defined in types.hal
+     */
+    oneway currentLinkCapacityEstimate(RadioIndicationType type, LinkCapacityEstimate lce);
+
+    /**
+     * Indicates physical channel configurations.
+     *
+     * @param type Type of radio indication
+     * @param configs List of PhysicalChannelConfigs as defined in types.hal
+     */
+    oneway currentPhysicalChannelConfigs(RadioIndicationType type,
+            vec<PhysicalChannelConfig> configs);
 };
diff --git a/radio/1.2/IRadioResponse.hal b/radio/1.2/IRadioResponse.hal
index a7ad30c..c356954 100644
--- a/radio/1.2/IRadioResponse.hal
+++ b/radio/1.2/IRadioResponse.hal
@@ -50,4 +50,26 @@
      *   RadioError:NONE
      */
     oneway getIccCardStatusResponse_1_2(RadioResponseInfo info, CardStatus cardStatus);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     */
+    oneway setSignalStrengthReportingCriteriaResponse(RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     */
+    oneway setLinkCapacityReportingCriteriaResponse(RadioResponseInfo info);
 };
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index 3aa2446..4515237 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -64,6 +64,67 @@
     MAX = 10,
 };
 
+enum CellConnectionStatus : int32_t {
+    /**
+     * Cell is not a serving cell.
+     */
+    NONE = 0,
+    /**
+     * UE has connection to cell for signalling and possibly data (3GPP 36.331, 25.331).
+     */
+    PRIMARY_SERVING,
+    /**
+     * UE has connection to cell for data (3GPP 36.331, 25.331).
+     */
+    SECONDARY_SERVING,
+};
+
+/**
+ * Overwritten from @1.0::IndicationFilter in order to redefine ALL. In the future, this should
+ * be extended instead of overwritten.
+ */
+enum IndicationFilter : int32_t {
+    NONE = 0,
+    ALL = ~0,
+    /**
+     * When this bit is set, modem must send the signal strength update through
+     * IRadioIndication.currentSignalStrength() when all criteria specified by
+     * IRadio.setSignalStrengthReportingCriteria() are met.
+     */
+    SIGNAL_STRENGTH = 1 << 0,
+    /**
+     * When this bit is set, modem must invoke IRadioIndication.networkStateChanged() when any field
+     * in VoiceRegStateResult or DataRegStateResult changes. When this bit is not set, modem must
+     * suppress IRadioIndication.networkStateChanged() when there are only changes from
+     * insignificant fields. Modem must invoke IRadioIndication.networkStateChanged() when
+     * significant fields are updated regardless of whether this bit is set.
+     *
+     * The following fields are considered significant: VoiceRegStateResult.regState,
+     * VoiceRegStateResult.rat, DataRegStateResult.regState, DataRegStateResult.rat.
+     */
+    FULL_NETWORK_STATE = 1 << 1,
+    /**
+     * When this bit is set, modem must send IRadioIndication.dataCallListChanged() whenever any
+     * field in ITypes.SetupDataCallResult changes. When this bit is not set, modem must suppress
+     * the indication when the only changed field is 'active' (for data dormancy). For all other
+     * field changes, the modem must send IRadioIndication.dataCallListChanged() regardless of
+     * whether this bit is set.
+     */
+    DATA_CALL_DORMANCY_CHANGED = 1 << 2,
+    /**
+     * When this bit is set, modem must send the link capacity update through
+     * IRadioIndication.currentLinkCapacityEstimate() when all criteria specified by
+     * IRadio.setLinkCapacityReportingCriteria() are met.
+     */
+    LINK_CAPACITY_ESTIMATE = 1 << 3,
+    /**
+     * When this bit is set, the modem must send the physical channel configuration update through
+     * IRadioIndication.currentPhysicalChannelConfigs() when the configuration has changed. It is
+     * recommended that this be reported whenever link capacity or signal strength is reported.
+     */
+    PHYSICAL_CHANNEL_CONFIG = 1 << 4,
+};
+
 struct NetworkScanRequest {
     ScanType type;
 
@@ -156,6 +217,10 @@
 struct CellIdentityLte {
     @1.0::CellIdentityLte base;
     CellIdentityOperatorNames operatorNames;
+    /**
+     * Cell bandwidth, in kHz.
+     */
+    int32_t bandwidth;
 };
 
 struct CellIdentityWcdma {
@@ -222,6 +287,10 @@
      * Valid only if type = tdscdma and size = 1 else must be empty.
      */
     vec<CellInfoTdscdma> tdscdma;
+    /**
+     * Connection status for the cell.
+     */
+    CellConnectionStatus connectionStatus;
 };
 
 struct CardStatus {
@@ -244,3 +313,25 @@
      */
     string iccid;
 };
+
+struct LinkCapacityEstimate {
+    /**
+     * Estimated downlink capacity in kbps.
+     */
+    uint32_t downlinkCapacityKbps;
+    /**
+     * Estimated uplink capacity in kbps.
+     */
+    uint32_t uplinkCapacityKbps;
+};
+
+struct PhysicalChannelConfig {
+    /**
+     * Connection status for cell. Valid values are PRIMARY_SERVING and SECONDARY_SERVING.
+     */
+    CellConnectionStatus status;
+    /**
+     * Cell bandwidth, in kHz.
+     */
+    int32_t cellBandwidthDownlink;
+};
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index ca3d3e4..24b58a7 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -15,8 +15,8 @@
  */
 
 #define LOG_TAG "sensors_hidl_hal_test"
-#include "GrallocWrapper.h"
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/sensors/1.0/ISensors.h>
 #include <android/hardware/sensors/1.0/types.h>
@@ -24,6 +24,7 @@
 #include <hardware/sensors.h>  // for sensor type strings
 #include <log/log.h>
 #include <utils/SystemClock.h>
+#include "GrallocWrapper.h"
 
 #include <algorithm>
 #include <cinttypes>
@@ -46,63 +47,65 @@
 
 // Test environment for sensors
 class SensorsHidlTest;
-class SensorsHidlEnvironment : public ::testing::Environment {
- public:
-  // get the test environment singleton
-  static SensorsHidlEnvironment* Instance() {
-    static SensorsHidlEnvironment* instance = new SensorsHidlEnvironment;
-    return instance;
-  }
+class SensorsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static SensorsHidlEnvironment* Instance() {
+        static SensorsHidlEnvironment* instance = new SensorsHidlEnvironment;
+        return instance;
+    }
 
-  virtual void SetUp();
-  virtual void TearDown();
+    virtual void HidlSetUp() override;
+    virtual void HidlTearDown() override;
 
-  // Get and clear all events collected so far (like "cat" shell command).
-  // If output is nullptr, it clears all collected events.
-  void catEvents(std::vector<Event>* output);
+    virtual void registerTestServices() override { registerTestService<ISensors>(); }
 
-  // set sensor event collection status
-  void setCollection(bool enable);
+    // Get and clear all events collected so far (like "cat" shell command).
+    // If output is nullptr, it clears all collected events.
+    void catEvents(std::vector<Event>* output);
 
- private:
-  friend SensorsHidlTest;
-  // sensors hidl service
-  sp<ISensors> sensors;
+    // set sensor event collection status
+    void setCollection(bool enable);
 
-  SensorsHidlEnvironment() {}
+   private:
+    friend SensorsHidlTest;
+    // sensors hidl service
+    sp<ISensors> sensors;
 
-  void addEvent(const Event& ev);
-  void startPollingThread();
-  void resetHal();
-  static void pollingThread(SensorsHidlEnvironment* env, std::shared_ptr<bool> stop);
+    SensorsHidlEnvironment() {}
 
-  bool collectionEnabled;
-  std::shared_ptr<bool> stopThread;
-  std::thread pollThread;
-  std::vector<Event> events;
-  std::mutex events_mutex;
+    void addEvent(const Event& ev);
+    void startPollingThread();
+    void resetHal();
+    static void pollingThread(SensorsHidlEnvironment* env, std::shared_ptr<bool> stop);
 
-  GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironment);
+    bool collectionEnabled;
+    std::shared_ptr<bool> stopThread;
+    std::thread pollThread;
+    std::vector<Event> events;
+    std::mutex events_mutex;
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsHidlEnvironment);
 };
 
-void SensorsHidlEnvironment::SetUp() {
-  resetHal();
+void SensorsHidlEnvironment::HidlSetUp() {
+    resetHal();
 
-  ASSERT_NE(sensors, nullptr) << "sensors is nullptr, cannot get hidl service";
+    ASSERT_NE(sensors, nullptr) << "sensors is nullptr, cannot get hidl service";
 
-  collectionEnabled = false;
-  startPollingThread();
+    collectionEnabled = false;
+    startPollingThread();
 
-  // In case framework just stopped for test and there is sensor events in the pipe,
-  // wait some time for those events to be cleared to avoid them messing up the test.
-  std::this_thread::sleep_for(std::chrono::seconds(3));
+    // In case framework just stopped for test and there is sensor events in the pipe,
+    // wait some time for those events to be cleared to avoid them messing up the test.
+    std::this_thread::sleep_for(std::chrono::seconds(3));
 }
 
-void SensorsHidlEnvironment::TearDown() {
-  if (stopThread) {
-    *stopThread = true;
-  }
-  pollThread.detach();
+void SensorsHidlEnvironment::HidlTearDown() {
+    if (stopThread) {
+        *stopThread = true;
+    }
+    pollThread.detach();
 }
 
 void SensorsHidlEnvironment::resetHal() {
@@ -115,7 +118,8 @@
     // this do ... while is for easy error handling
     do {
       step = "getService()";
-      sensors = ISensors::getService();
+      sensors = ISensors::getService(
+          SensorsHidlEnvironment::Instance()->getServiceName<ISensors>());
       if (sensors == nullptr) {
         break;
       }
@@ -1500,6 +1504,7 @@
 int main(int argc, char **argv) {
   ::testing::AddGlobalTestEnvironment(SensorsHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
+  SensorsHidlEnvironment::Instance()->init(&argc, argv);
   int status = RUN_ALL_TESTS();
   ALOGI("Test result = %d", status);
   return status;
diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..7a920b4
--- /dev/null
+++ b/wifi/hostapd/1.0/vts/functional/Android.bp
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_static {
+    name: "VtsHalWifiHostapdV1_0TargetTestUtil",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["hostapd_hidl_test_utils.cpp"],
+    export_include_dirs: [
+        "."
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi.hostapd@1.0",
+        "android.hardware.wifi@1.0",
+        "libcrypto",
+        "libgmock",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiHostapdV1_0TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "VtsHalWifiHostapdV1_0TargetTest.cpp",
+        "hostapd_hidl_test.cpp",
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiHostapdV1_0TargetTestUtil",
+        "android.hardware.wifi.hostapd@1.0",
+        "android.hardware.wifi@1.0",
+        "libcrypto",
+        "libgmock",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+}
diff --git a/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp b/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
new file mode 100644
index 0000000..64e6fbe
--- /dev/null
+++ b/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include "hostapd_hidl_test_utils.h"
+
+class HostapdHidlEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() override { stopHostapd(); }
+    virtual void TearDown() override { startHostapdAndWaitForHidlService(); }
+};
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new HostapdHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h
new file mode 100644
index 0000000..2f71ccb
--- /dev/null
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This file is copied from
+// hardware/interfaces/wifi/1.0/vts/functional/wifi_hidl_call_util.h
+// Please make sure these two file are consistent.
+
+#pragma once
+
+#include <functional>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace {
+namespace detail {
+template <typename>
+struct functionArgSaver;
+
+// Provides a std::function that takes one argument, and a buffer
+// wherein the function will store its argument. The buffer has
+// the same type as the argument, but with const and reference
+// modifiers removed.
+template <typename ArgT>
+struct functionArgSaver<std::function<void(ArgT)>> final {
+    using StorageT = typename std::remove_const<
+        typename std::remove_reference<ArgT>::type>::type;
+
+    std::function<void(ArgT)> saveArgs = [this](ArgT arg) {
+        this->saved_values = arg;
+    };
+
+    StorageT saved_values;
+};
+
+// Provides a std::function that takes two arguments, and a buffer
+// wherein the function will store its arguments. The buffer is a
+// std::pair, whose elements have the same types as the arguments
+// (but with const and reference modifiers removed).
+template <typename Arg1T, typename Arg2T>
+struct functionArgSaver<std::function<void(Arg1T, Arg2T)>> final {
+    using StorageT =
+        std::pair<typename std::remove_const<
+                      typename std::remove_reference<Arg1T>::type>::type,
+                  typename std::remove_const<
+                      typename std::remove_reference<Arg2T>::type>::type>;
+
+    std::function<void(Arg1T, Arg2T)> saveArgs = [this](Arg1T arg1,
+                                                        Arg2T arg2) {
+        this->saved_values = {arg1, arg2};
+    };
+
+    StorageT saved_values;
+};
+
+// Provides a std::function that takes three or more arguments, and a
+// buffer wherein the function will store its arguments. The buffer is a
+// std::tuple whose elements have the same types as the arguments (but
+// with const and reference modifiers removed).
+template <typename... ArgT>
+struct functionArgSaver<std::function<void(ArgT...)>> final {
+    using StorageT = std::tuple<typename std::remove_const<
+        typename std::remove_reference<ArgT>::type>::type...>;
+
+    std::function<void(ArgT...)> saveArgs = [this](ArgT... arg) {
+        this->saved_values = {arg...};
+    };
+
+    StorageT saved_values;
+};
+
+// Invokes |method| on |object|, providing |method| a CallbackT as the
+// final argument. Returns a copy of the parameters that |method| provided
+// to CallbackT. (The parameters are returned by value.)
+template <typename CallbackT, typename MethodT, typename ObjectT,
+          typename... ArgT>
+typename functionArgSaver<CallbackT>::StorageT invokeMethod(
+    MethodT method, ObjectT object, ArgT&&... methodArg) {
+    functionArgSaver<CallbackT> result_buffer;
+    const auto& res = ((*object).*method)(std::forward<ArgT>(methodArg)...,
+                                          result_buffer.saveArgs);
+    EXPECT_TRUE(res.isOk());
+    return result_buffer.saved_values;
+}
+}  // namespace detail
+}  // namespace
+
+// Invokes |method| on |strong_pointer|, passing provided arguments through to
+// |method|.
+//
+// Returns either:
+// - A copy of the result callback parameter (for callbacks with a single
+//   parameter), OR
+// - A pair containing a copy of the result callback parameters (for callbacks
+//   with two parameters), OR
+// - A tuple containing a copy of the result callback paramters (for callbacks
+//   with three or more parameters).
+//
+// Example usage:
+//   EXPECT_EQ(HostapdStatusCode::SUCCESS,
+//       HIDL_INVOKE(strong_pointer, methodReturningHostapdStatus).code);
+//   EXPECT_EQ(HostapdStatusCode::SUCCESS,
+//       HIDL_INVOKE(strong_pointer, methodReturningHostapdStatusAndOneMore)
+//         .first.code);
+//   EXPECT_EQ(HostapdStatusCode::SUCCESS, std::get<0>(
+//       HIDL_INVOKE(strong_pointer, methodReturningHostapdStatusAndTwoMore))
+//         .code);
+#define HIDL_INVOKE(strong_pointer, method, ...)                              \
+    (detail::invokeMethod<                                                    \
+        std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
+        &std::remove_reference<decltype(*strong_pointer)>::type::method,      \
+        strong_pointer, ##__VA_ARGS__))
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
new file mode 100644
index 0000000..5f51cfb
--- /dev/null
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+#include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
+
+#include "hostapd_hidl_call_util.h"
+#include "hostapd_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::wifi::hostapd::V1_0::IHostapd;
+using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus;
+using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode;
+
+namespace {
+constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
+                                     '2', '3', '4', '5'};
+constexpr char kNwPassphrase[] = "test12345";
+constexpr int kIfaceChannel = 6;
+constexpr int kIfaceInvalidChannel = 567;
+}  // namespace
+
+class HostapdHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        startHostapdAndWaitForHidlService();
+        hostapd_ = getHostapd();
+        ASSERT_NE(hostapd_.get(), nullptr);
+    }
+
+    virtual void TearDown() override { stopHostapd(); }
+
+   protected:
+    std::string getPrimaryWlanIfaceName() {
+        std::array<char, PROPERTY_VALUE_MAX> buffer;
+        property_get("wifi.interface", buffer.data(), "wlan0");
+        return buffer.data();
+    }
+
+    IHostapd::IfaceParams getIfaceParamsWithAcs() {
+        IHostapd::IfaceParams iface_params;
+        iface_params.ifaceName = getPrimaryWlanIfaceName();
+        iface_params.hwModeParams.enable80211N = true;
+        iface_params.hwModeParams.enable80211AC = false;
+        iface_params.channelParams.enableAcs = true;
+        iface_params.channelParams.acsShouldExcludeDfs = true;
+        iface_params.channelParams.channel = 0;
+        iface_params.channelParams.band = IHostapd::Band::BAND_ANY;
+        return iface_params;
+    }
+
+    IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+        IHostapd::IfaceParams iface_params;
+        iface_params.ifaceName = getPrimaryWlanIfaceName();
+        iface_params.hwModeParams.enable80211N = true;
+        iface_params.hwModeParams.enable80211AC = false;
+        iface_params.channelParams.enableAcs = false;
+        iface_params.channelParams.acsShouldExcludeDfs = false;
+        iface_params.channelParams.channel = kIfaceChannel;
+        iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ;
+        return iface_params;
+    }
+
+    IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
+        IHostapd::IfaceParams iface_params;
+        iface_params.ifaceName = getPrimaryWlanIfaceName();
+        iface_params.hwModeParams.enable80211N = true;
+        iface_params.hwModeParams.enable80211AC = false;
+        iface_params.channelParams.enableAcs = false;
+        iface_params.channelParams.acsShouldExcludeDfs = false;
+        iface_params.channelParams.channel = kIfaceInvalidChannel;
+        iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ;
+        return iface_params;
+    }
+
+    IHostapd::NetworkParams getPskNwParams() {
+        IHostapd::NetworkParams nw_params;
+        nw_params.ssid =
+            std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+        nw_params.isHidden = false;
+        nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
+        nw_params.pskPassphrase = kNwPassphrase;
+        return nw_params;
+    }
+
+    IHostapd::NetworkParams getInvalidPskNwParams() {
+        IHostapd::NetworkParams nw_params;
+        nw_params.ssid =
+            std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+        nw_params.isHidden = false;
+        nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
+        return nw_params;
+    }
+
+    IHostapd::NetworkParams getOpenNwParams() {
+        IHostapd::NetworkParams nw_params;
+        nw_params.ssid =
+            std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
+        nw_params.isHidden = false;
+        nw_params.encryptionType = IHostapd::EncryptionType::NONE;
+        return nw_params;
+    }
+    // IHostapd object used for all tests in this fixture.
+    sp<IHostapd> hostapd_;
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IHostapd proxy object is
+ * successfully created.
+ */
+TEST(HostapdHidlTestNoFixture, Create) {
+    startHostapdAndWaitForHidlService();
+    EXPECT_NE(nullptr, getHostapd().get());
+    stopHostapd();
+}
+
+/**
+ * Adds an access point with PSK network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) {
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithAcs(),
+                              getPskNwParams());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS enabled.
+ * Access point creation should pass.
+ */
+TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithAcs(),
+                              getOpenNwParams());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with PSK network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_F(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
+                              getIfaceParamsWithoutAcs(), getPskNwParams());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with Open network config & ACS disabled.
+ * Access point creation should pass.
+ */
+TEST_F(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
+                              getIfaceParamsWithoutAcs(), getOpenNwParams());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS enabled.
+ * Access point creation & removal should pass.
+ */
+TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) {
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithAcs(),
+                              getPskNwParams());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+    status =
+        HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds & then removes an access point with PSK network config & ACS disabled.
+ * Access point creation & removal should pass.
+ */
+TEST_F(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
+                              getIfaceParamsWithoutAcs(), getPskNwParams());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+    status =
+        HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+    EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid channel.
+ * Access point creation should fail.
+ */
+TEST_F(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+    auto status =
+        HIDL_INVOKE(hostapd_, addAccessPoint,
+                    getIfaceParamsWithInvalidChannel(), getPskNwParams());
+    EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
+
+/**
+ * Adds an access point with invalid PSK network config.
+ * Access point creation should fail.
+ */
+TEST_F(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+    auto status =
+        HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(),
+                    getInvalidPskNwParams());
+    EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
+}
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
new file mode 100644
index 0000000..0915150
--- /dev/null
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <android/hidl/manager/1.0/IServiceNotification.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include <wifi_system/hostapd_manager.h>
+#include <wifi_system/interface_tool.h>
+
+#include "hostapd_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::hardware::wifi::hostapd::V1_0::IHostapd;
+using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus;
+using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode;
+using ::android::hidl::manager::V1_0::IServiceNotification;
+using ::android::wifi_system::HostapdManager;
+
+namespace {
+const char kHostapdServiceName[] = "default";
+
+// Helper function to initialize the driver and firmware to AP mode
+// using the vendor HAL HIDL interface.
+void initilializeDriverAndFirmware() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    ChipModeId mode_id;
+    EXPECT_TRUE(configureChipToSupportIfaceType(
+        wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::AP, &mode_id));
+}
+
+// Helper function to deinitialize the driver and firmware
+// using the vendor HAL HIDL interface.
+void deInitilializeDriverAndFirmware() { stopWifi(); }
+}  // namespace
+
+// Utility class to wait for wpa_hostapd's HIDL service registration.
+class ServiceNotificationListener : public IServiceNotification {
+   public:
+    Return<void> onRegistration(const hidl_string& fully_qualified_name,
+                                const hidl_string& instance_name,
+                                bool pre_existing) override {
+        if (pre_existing) {
+            return Void();
+        }
+        std::unique_lock<std::mutex> lock(mutex_);
+        registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
+                              instance_name.c_str());
+        lock.unlock();
+        condition_.notify_one();
+        return Void();
+    }
+
+    bool registerForHidlServiceNotifications(const std::string& instance_name) {
+        if (!IHostapd::registerForNotifications(instance_name, this)) {
+            return false;
+        }
+        configureRpcThreadpool(2, false);
+        return true;
+    }
+
+    bool waitForHidlService(uint32_t timeout_in_millis,
+                            const std::string& instance_name) {
+        std::unique_lock<std::mutex> lock(mutex_);
+        condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
+                            [&]() { return registered_.size() >= 1; });
+        if (registered_.size() != 1) {
+            return false;
+        }
+        std::string expected_registered =
+            std::string(IHostapd::descriptor) + "/" + instance_name;
+        if (registered_[0] != expected_registered) {
+            LOG(ERROR) << "Expected: " << expected_registered
+                       << ", Got: " << registered_[0];
+            return false;
+        }
+        return true;
+    }
+
+   private:
+    std::vector<std::string> registered_{};
+    std::mutex mutex_;
+    std::condition_variable condition_;
+};
+
+void stopHostapd() {
+    HostapdManager hostapd_manager;
+
+    ASSERT_TRUE(hostapd_manager.StopHostapd());
+    deInitilializeDriverAndFirmware();
+}
+
+void startHostapdAndWaitForHidlService() {
+    initilializeDriverAndFirmware();
+
+    android::sp<ServiceNotificationListener> notification_listener =
+        new ServiceNotificationListener();
+    ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
+        kHostapdServiceName));
+
+    HostapdManager hostapd_manager;
+    ASSERT_TRUE(hostapd_manager.StartHostapd());
+
+    ASSERT_TRUE(
+        notification_listener->waitForHidlService(200, kHostapdServiceName));
+}
+
+sp<IHostapd> getHostapd() {
+    return ::testing::VtsHalHidlTargetTestBase::getService<IHostapd>();
+}
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
new file mode 100644
index 0000000..74ed284
--- /dev/null
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HOSTAPD_HIDL_TEST_UTILS_H
+#define HOSTAPD_HIDL_TEST_UTILS_H
+
+#include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
+
+// Used to stop the android wifi framework before every test.
+void stopWifiFramework();
+void startWifiFramework();
+void stopHostapd();
+// Used to configure the chip, driver and start wpa_hostapd before every
+// test.
+void startHostapdAndWaitForHidlService();
+
+// Helper functions to obtain references to the various HIDL interface objects.
+// Note: We only have a single instance of each of these objects currently.
+// These helper functions should be modified to return vectors if we support
+// multiple instances.
+android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd> getHostapd();
+
+#endif /* HOSTAPD_HIDL_TEST_UTILS_H */