Merge "Use explicit .c_str() for hidl_string" into oc-dev
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..787d47a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2017 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.
+#
+
+#
+# Below are some minor deviations from the default Google style to
+# accommodate for handling of the large legacy code base.
+#
+
+BasedOnStyle: Google
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+AllowShortFunctionsOnASingleLine: Inline
+TabWidth: 4
+UseTab: Never
+IndentWidth: 4
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..213c93a
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,5 @@
+[Options]
+ignore_merged_commits = true
+
+[Builtin Hooks]
+clang_format = true
diff --git a/automotive/vehicle/2.0/default/Android.mk b/automotive/vehicle/2.0/default/Android.mk
index b8535bd..3c56159 100644
--- a/automotive/vehicle/2.0/default/Android.mk
+++ b/automotive/vehicle/2.0/default/Android.mk
@@ -25,6 +25,7 @@
     common/src/SubscriptionManager.cpp \
     common/src/VehicleHalManager.cpp \
     common/src/VehicleObjectPool.cpp \
+    common/src/VehiclePropertyStore.cpp \
     common/src/VehicleUtils.cpp \
 
 LOCAL_C_INCLUDES := \
@@ -72,9 +73,10 @@
 
 LOCAL_MODULE:= $(vhal_v2_0)-default-impl-lib
 LOCAL_SRC_FILES:= \
-    impl/vhal_v2_0/DefaultVehicleHal.cpp \
+    impl/vhal_v2_0/EmulatedVehicleHal.cpp \
+    impl/vhal_v2_0/VehicleEmulator.cpp \
     impl/vhal_v2_0/PipeComm.cpp \
-    impl/vhal_v2_0/SocketComm.cpp
+    impl/vhal_v2_0/SocketComm.cpp \
 
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/impl/vhal_v2_0
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 95057cc..e6d292e 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -21,14 +21,16 @@
 #include <iostream>
 
 #include <vhal_v2_0/VehicleHalManager.h>
-#include <vhal_v2_0/DefaultVehicleHal.h>
+#include <vhal_v2_0/EmulatedVehicleHal.h>
 
 using namespace android;
 using namespace android::hardware;
 using namespace android::hardware::automotive::vehicle::V2_0;
 
 int main(int /* argc */, char* /* argv */ []) {
-    auto hal = std::make_unique<impl::DefaultVehicleHal>();
+    auto store = std::make_unique<VehiclePropertyStore>();
+    auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get());
+    auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
     auto service = std::make_unique<VehicleHalManager>(hal.get());
 
     configureRpcThreadpool(1, true /* callerWillJoin */);
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
new file mode 100644
index 0000000..eda94b7
--- /dev/null
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 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 android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_
+
+#include <cstdint>
+#include <unordered_map>
+#include <memory>
+#include <mutex>
+
+#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+/**
+ * Encapsulates work related to storing and accessing configuration, storing and modifying
+ * vehicle property values.
+ *
+ * VehiclePropertyValues stored in a sorted map thus it makes easier to get range of values, e.g.
+ * to get value for all areas for particular property.
+ *
+ * This class is thread-safe, however it uses blocking synchronization across all methods.
+ */
+class VehiclePropertyStore {
+public:
+    /* Function that used to calculate unique token for given VehiclePropValue */
+    using TokenFunction = std::function<int64_t(const VehiclePropValue& value)>;
+
+private:
+    struct RecordConfig {
+        VehiclePropConfig propConfig;
+        TokenFunction tokenFunction;
+    };
+
+    struct RecordId {
+        int32_t prop;
+        int32_t area;
+        int64_t token;
+
+        bool operator==(const RecordId& other) const;
+        bool operator<(const RecordId& other) const;
+    };
+
+    using PropertyMap = std::map<RecordId, VehiclePropValue>;
+    using PropertyMapRange = std::pair<PropertyMap::const_iterator, PropertyMap::const_iterator>;
+
+public:
+    void registerProperty(const VehiclePropConfig& config, TokenFunction tokenFunc = nullptr);
+
+    /* Stores provided value. Returns true if value was written returns false if config for
+     * example wasn't registered. */
+    bool writeValue(const VehiclePropValue& propValue);
+
+    void removeValue(const VehiclePropValue& propValue);
+    void removeValuesForProperty(int32_t propId);
+
+    std::vector<VehiclePropValue> readAllValues() const;
+    std::vector<VehiclePropValue> readValuesForProperty(int32_t propId) const;
+    std::unique_ptr<VehiclePropValue> readValueOrNull(const VehiclePropValue& request) const;
+    std::unique_ptr<VehiclePropValue> readValueOrNull(int32_t prop, int32_t area = 0,
+                                                      int64_t token = 0) const;
+
+    std::vector<VehiclePropConfig> getAllConfigs() const;
+    const VehiclePropConfig* getConfigOrNull(int32_t propId) const;
+    const VehiclePropConfig* getConfigOrDie(int32_t propId) const;
+
+private:
+    RecordId getRecordIdLocked(const VehiclePropValue& valuePrototype) const;
+    const VehiclePropValue* getValueOrNullLocked(const RecordId& recId) const;
+    PropertyMapRange findRangeLocked(int32_t propId) const;
+
+private:
+    using MuxGuard = std::lock_guard<std::mutex>;
+    mutable std::mutex mLock;
+    std::unordered_map<int32_t /* VehicleProperty */, RecordConfig> mConfigs;
+
+    PropertyMap mPropertyValues;  // Sorted map of RecordId : VehiclePropValue.
+};
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif //android_hardware_automotive_vehicle_V2_0_impl_PropertyDb_H_
diff --git a/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
new file mode 100644
index 0000000..0e6b776
--- /dev/null
+++ b/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "VehiclePropertyStore"
+#include <android/log.h>
+
+#include <common/include/vhal_v2_0/VehicleUtils.h>
+#include "VehiclePropertyStore.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+bool VehiclePropertyStore::RecordId::operator==(const VehiclePropertyStore::RecordId& other) const {
+    return prop == other.prop && area == other.area && token == other.token;
+}
+
+bool VehiclePropertyStore::RecordId::operator<(const VehiclePropertyStore::RecordId& other) const  {
+    return prop < other.prop
+           || (prop == other.prop && area < other.area)
+           || (prop == other.prop && area == other.area && token < other.token);
+}
+
+void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,
+                                            VehiclePropertyStore::TokenFunction tokenFunc) {
+    MuxGuard g(mLock);
+    mConfigs.insert({ config.prop, RecordConfig { config, tokenFunc } });
+}
+
+bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue) {
+    MuxGuard g(mLock);
+    if (!mConfigs.count(propValue.prop)) return false;
+
+    RecordId recId = getRecordIdLocked(propValue);
+    VehiclePropValue* valueToUpdate = const_cast<VehiclePropValue*>(getValueOrNullLocked(recId));
+    if (valueToUpdate == nullptr) {
+        mPropertyValues.insert({ recId, propValue });
+    } else {
+        valueToUpdate->timestamp = propValue.timestamp;
+        valueToUpdate->value = propValue.value;
+    }
+    return true;
+}
+
+void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) {
+    MuxGuard g(mLock);
+    RecordId recId = getRecordIdLocked(propValue);
+    auto it = mPropertyValues.find(recId);
+    if (it != mPropertyValues.end()) {
+        mPropertyValues.erase(it);
+    }
+}
+
+void VehiclePropertyStore::removeValuesForProperty(int32_t propId) {
+    MuxGuard g(mLock);
+    auto range = findRangeLocked(propId);
+    mPropertyValues.erase(range.first, range.second);
+}
+
+std::vector<VehiclePropValue> VehiclePropertyStore::readAllValues() const {
+    MuxGuard g(mLock);
+    std::vector<VehiclePropValue> allValues;
+    allValues.reserve(mPropertyValues.size());
+    for (auto&& it : mPropertyValues) {
+        allValues.push_back(it.second);
+    }
+    return allValues;
+}
+
+std::vector<VehiclePropValue> VehiclePropertyStore::readValuesForProperty(int32_t propId) const {
+    std::vector<VehiclePropValue> values;
+    MuxGuard g(mLock);
+    auto range = findRangeLocked(propId);
+    for (auto it = range.first; it != range.second; ++it) {
+        values.push_back(it->second);
+    }
+
+    return values;
+}
+
+std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull(
+        const VehiclePropValue& request) const {
+    MuxGuard g(mLock);
+    RecordId recId = getRecordIdLocked(request);
+    const VehiclePropValue* internalValue = getValueOrNullLocked(recId);
+    return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr;
+}
+
+std::unique_ptr<VehiclePropValue> VehiclePropertyStore::readValueOrNull(
+        int32_t prop, int32_t area, int64_t token) const {
+    RecordId recId = {prop, isGlobalProp(prop) ? 0 : area, token };
+    MuxGuard g(mLock);
+    const VehiclePropValue* internalValue = getValueOrNullLocked(recId);
+    return internalValue ? std::make_unique<VehiclePropValue>(*internalValue) : nullptr;
+}
+
+
+std::vector<VehiclePropConfig> VehiclePropertyStore::getAllConfigs() const {
+    MuxGuard g(mLock);
+    std::vector<VehiclePropConfig> configs;
+    configs.reserve(mConfigs.size());
+    for (auto&& recordConfigIt: mConfigs) {
+        configs.push_back(recordConfigIt.second.propConfig);
+    }
+    return configs;
+}
+
+const VehiclePropConfig* VehiclePropertyStore::getConfigOrNull(int32_t propId) const {
+    MuxGuard g(mLock);
+    auto recordConfigIt = mConfigs.find(propId);
+    return recordConfigIt != mConfigs.end() ? &recordConfigIt->second.propConfig : nullptr;
+}
+
+const VehiclePropConfig* VehiclePropertyStore::getConfigOrDie(int32_t propId) const {
+    auto cfg = getConfigOrNull(propId);
+    if (!cfg) {
+        ALOGW("%s: config not found for property: 0x%x", __func__, propId);
+        abort();
+    }
+    return cfg;
+}
+
+VehiclePropertyStore::RecordId VehiclePropertyStore::getRecordIdLocked(
+        const VehiclePropValue& valuePrototype) const {
+    RecordId recId = {
+        .prop = valuePrototype.prop,
+        .area = isGlobalProp(valuePrototype.prop) ? 0 : valuePrototype.areaId,
+        .token = 0
+    };
+
+    auto it = mConfigs.find(recId.prop);
+    if (it == mConfigs.end()) return {};
+
+    if (it->second.tokenFunction != nullptr) {
+        recId.token = it->second.tokenFunction(valuePrototype);
+    }
+    return recId;
+}
+
+const VehiclePropValue* VehiclePropertyStore::getValueOrNullLocked(
+        const VehiclePropertyStore::RecordId& recId) const  {
+    auto it = mPropertyValues.find(recId);
+    return it == mPropertyValues.end() ? nullptr : &it->second;
+}
+
+VehiclePropertyStore::PropertyMapRange VehiclePropertyStore::findRangeLocked(int32_t propId) const {
+    // Based on the fact that mPropertyValues is a sorted map by RecordId.
+    auto beginIt = mPropertyValues.lower_bound( RecordId { propId, INT32_MIN, 0 });
+    auto endIt = mPropertyValues.lower_bound( RecordId { propId + 1, INT32_MIN, 0 });
+
+    return  PropertyMapRange { beginIt, endIt };
+}
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
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 545de39..bf16a9b 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
@@ -33,176 +33,257 @@
     toInt(VehicleProperty::HVAC_FAN_DIRECTION),
 };
 
-const VehiclePropConfig kVehicleProperties[] = {
+struct ConfigDeclaration {
+    VehiclePropConfig config;
+
+    /* This value will be used as an initial value for the property. If this field is specified for
+     * property that supports multiple areas then it will be used for all areas unless particular
+     * area is overridden in initialAreaValue field. */
+    VehiclePropValue::RawValue initialValue;
+    /* Use initialAreaValues if it is necessary to specify different values per each area. */
+    std::map<int32_t, VehiclePropValue::RawValue> initialAreaValues;
+};
+
+const ConfigDeclaration kVehicleProperties[] {
     {
-        .prop = toInt(VehicleProperty::INFO_MAKE),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::STATIC,
+        .config = {
+            .prop = toInt(VehicleProperty::INFO_MAKE),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::STATIC,
+        },
+        .initialValue = { .stringValue = "Toy Vehicle" }
+    },
+    {
+        .config = {
+            .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .floatValues = {0.0f} }
     },
 
     {
-        .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .config = {
+            .prop = toInt(VehicleProperty::CURRENT_GEAR),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = { toInt(VehicleGear::GEAR_PARK) } }
     },
 
     {
-        .prop = toInt(VehicleProperty::CURRENT_GEAR),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .config = {
+            .prop = toInt(VehicleProperty::PARKING_BRAKE_ON),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = {1} }
     },
 
     {
-        .prop = toInt(VehicleProperty::PARKING_BRAKE_ON),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .config = {
+            .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = {0} }
     },
 
     {
-        .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        .config = {
+            .prop = toInt(VehicleProperty::HVAC_POWER_ON),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .supportedAreas = toInt(VehicleAreaZone::ROW_1),
+            // TODO(bryaneyler): Ideally, this is generated dynamically from
+            // kHvacPowerProperties.
+            .configString = "0x12400500,0x12400501"  // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION
+        },
+        .initialValue = { .int32Values = {1} }
     },
 
     {
-        .prop = toInt(VehicleProperty::HVAC_POWER_ON),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas = toInt(VehicleAreaZone::ROW_1),
-        // TODO(bryaneyler): Ideally, this is generated dynamically from
-        // kHvacPowerProperties.
-        .configString = "0x12400500,0x12400501"  // HVAC_FAN_SPEED,HVAC_FAN_DIRECTION
+        .config = {
+            .prop = toInt(VehicleProperty::HVAC_DEFROSTER),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .supportedAreas =
+            VehicleAreaWindow::FRONT_WINDSHIELD
+            | VehicleAreaWindow::REAR_WINDSHIELD
+        },
+        .initialValue = { .int32Values = {0} }  // Will be used for all areas.
     },
 
     {
-        .prop = toInt(VehicleProperty::HVAC_DEFROSTER),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas =
-                VehicleAreaWindow::FRONT_WINDSHIELD
-                | VehicleAreaWindow::REAR_WINDSHIELD
+        .config = {
+            .prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .supportedAreas = toInt(VehicleAreaZone::ROW_1)
+        },
+        .initialValue = { .int32Values = {1} }
     },
 
     {
-        .prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas = toInt(VehicleAreaZone::ROW_1)
+        .config = {
+            .prop = toInt(VehicleProperty::HVAC_AC_ON),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .supportedAreas = toInt(VehicleAreaZone::ROW_1)
+        },
+        .initialValue = { .int32Values = {1} }
     },
 
     {
-        .prop = toInt(VehicleProperty::HVAC_AC_ON),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas = toInt(VehicleAreaZone::ROW_1)
+        .config = {
+            .prop = toInt(VehicleProperty::HVAC_AUTO_ON),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .supportedAreas = toInt(VehicleAreaZone::ROW_1)
+        },
+        .initialValue = { .int32Values = {1} }
     },
 
     {
-        .prop = toInt(VehicleProperty::HVAC_AUTO_ON),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas = toInt(VehicleAreaZone::ROW_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
+                }
+            }
+        },
+        .initialValue = { .int32Values = {3} }
     },
 
     {
-        .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
+        .config = {
+            .prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .supportedAreas = toInt(VehicleAreaZone::ROW_1),
+        },
+        .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,
+                    .maxFloatValue = 32,
+                },
+                VehicleAreaConfig {
+                    .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
+                    .minFloatValue = 16,
+                    .maxFloatValue = 32,
+                }
+            }
+        },
+        .initialAreaValues = {
+            {
+                toInt(VehicleAreaZone::ROW_1_LEFT),
+                { .floatValues = {16} }
+            }, {
+                toInt(VehicleAreaZone::ROW_1_RIGHT),
+                { .floatValues = {20} }
             }
         }
     },
 
     {
-        .prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .supportedAreas = toInt(VehicleAreaZone::ROW_1),
+        .config = {
+            .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
+            .access = VehiclePropertyAccess::READ,
+            // TODO(bryaneyler): Support ON_CHANGE as well.
+            .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+            .minSampleRate = 1.0f,
+            .maxSampleRate = 2.0f,
+        },
+        .initialValue = { .floatValues = {25.0f} }
     },
 
     {
-        .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,
-                .maxFloatValue = 32,
-            },
-            VehicleAreaConfig {
-                .areaId = toInt(VehicleAreaZone::ROW_1_RIGHT),
-                .minFloatValue = 16,
-                .maxFloatValue = 32,
+        .config = {
+            .prop = toInt(VehicleProperty::NIGHT_MODE),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = {0} }
+    },
+
+    {
+        .config = {
+            .prop = toInt(VehicleProperty::DRIVING_STATUS),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = { toInt(VehicleDrivingStatus::UNRESTRICTED) } }
+    },
+
+    {
+        .config = {
+            .prop = toInt(VehicleProperty::GEAR_SELECTION),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = { toInt(VehicleGear::GEAR_PARK) } }
+    },
+
+    {
+        .config = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::STATIC,
+        },
+        .initialValue = { .floatValues = { 123000.0f } }  // In Milliliters
+    },
+
+    {
+        .config = {
+            .prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
+            .access = VehiclePropertyAccess::READ_WRITE,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+            .areaConfigs = {
+                VehicleAreaConfig {
+                    .minInt32Value = 0,
+                    .maxInt32Value = 10
+                }
             }
-        }
+        },
+        .initialValue = { .int32Values = {7} }
     },
 
     {
-        .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
-        .access = VehiclePropertyAccess::READ,
-        // TODO(bryaneyler): Support ON_CHANGE as well.
-        .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-        .minSampleRate = 1.0f,
-        .maxSampleRate = 2.0f,
+        .config = {
+            .prop = toInt(VehicleProperty::IGNITION_STATE),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+        },
+        .initialValue = { .int32Values = { toInt(VehicleIgnitionState::ON) } }
     },
 
     {
-        .prop = toInt(VehicleProperty::NIGHT_MODE),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-    },
-
-    {
-        .prop = toInt(VehicleProperty::DRIVING_STATUS),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-    },
-
-    {
-        .prop = toInt(VehicleProperty::GEAR_SELECTION),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-    },
-
-    {
-        .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::STATIC,
-    },
-
-    {
-        .prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
-        .access = VehiclePropertyAccess::READ_WRITE,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-        .areaConfigs = {
-            VehicleAreaConfig {
-                .minInt32Value = 0,
-                .maxInt32Value = 10
-            }
-        }
-    },
-
-    {
-        .prop = toInt(VehicleProperty::IGNITION_STATE),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-    },
-
-    {
-        .prop = toInt(VehicleProperty::ENGINE_OIL_TEMP),
-        .access = VehiclePropertyAccess::READ,
-        .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
-        .minSampleRate = 0.1, // 0.1 Hz, every 10 seconds
-        .maxSampleRate = 10,  // 10 Hz, every 100 ms
+        .config = {
+            .prop = toInt(VehicleProperty::ENGINE_OIL_TEMP),
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+            .minSampleRate = 0.1, // 0.1 Hz, every 10 seconds
+            .maxSampleRate = 10,  // 10 Hz, every 100 ms
+        },
+        .initialValue = { .floatValues = {101.0f} }
     }
 };
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
deleted file mode 100644
index 03a65f3..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "DefaultVehicleHal_v2_0"
-#include <android/log.h>
-
-#include <algorithm>
-#include <android-base/properties.h>
-#include <cstdio>
-
-#include "DefaultVehicleHal.h"
-#include "PipeComm.h"
-#include "SocketComm.h"
-#include "VehicleHalProto.pb.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-void DefaultVehicleHal::doGetConfig(emulator::EmulatorMessage& rxMsg,
-                                    emulator::EmulatorMessage& respMsg) {
-    std::vector<VehiclePropConfig> configs = listProperties();
-    emulator::VehiclePropGet getProp = rxMsg.prop(0);
-
-    respMsg.set_msg_type(emulator::GET_CONFIG_RESP);
-    respMsg.set_status(emulator::ERROR_INVALID_PROPERTY);
-
-    for (auto& config : configs) {
-        // Find the config we are looking for
-        if (config.prop == getProp.prop()) {
-            emulator::VehiclePropConfig* protoCfg = respMsg.add_config();
-            populateProtoVehicleConfig(protoCfg, config);
-            respMsg.set_status(emulator::RESULT_OK);
-            break;
-        }
-    }
-}
-
-void DefaultVehicleHal::doGetConfigAll(emulator::EmulatorMessage& /* rxMsg */,
-                                       emulator::EmulatorMessage& respMsg) {
-    std::vector<VehiclePropConfig> configs = listProperties();
-
-    respMsg.set_msg_type(emulator::GET_CONFIG_ALL_RESP);
-    respMsg.set_status(emulator::RESULT_OK);
-
-    for (auto& config : configs) {
-        emulator::VehiclePropConfig* protoCfg = respMsg.add_config();
-        populateProtoVehicleConfig(protoCfg, config);
-    }
-}
-
-void DefaultVehicleHal::doGetProperty(emulator::EmulatorMessage& rxMsg,
-                                      emulator::EmulatorMessage& respMsg) {
-    int32_t areaId = 0;
-    emulator::VehiclePropGet getProp = rxMsg.prop(0);
-    int32_t propId = getProp.prop();
-    emulator::Status status = emulator::ERROR_INVALID_PROPERTY;
-    VehiclePropValue* val;
-
-    respMsg.set_msg_type(emulator::GET_PROPERTY_RESP);
-
-    if (getProp.has_area_id()) {
-        areaId = getProp.area_id();
-    }
-
-    {
-        std::lock_guard<std::mutex> lock(mPropsMutex);
-
-        val = getVehiclePropValueLocked(propId, areaId);
-        if (val != nullptr) {
-            emulator::VehiclePropValue* protoVal = respMsg.add_value();
-            populateProtoVehiclePropValue(protoVal, val);
-            status = emulator::RESULT_OK;
-        }
-    }
-
-    respMsg.set_status(status);
-}
-
-void DefaultVehicleHal::doGetPropertyAll(emulator::EmulatorMessage& /* rxMsg */,
-                                         emulator::EmulatorMessage& respMsg) {
-    respMsg.set_msg_type(emulator::GET_PROPERTY_ALL_RESP);
-    respMsg.set_status(emulator::RESULT_OK);
-
-    {
-        std::lock_guard<std::mutex> lock(mPropsMutex);
-
-        for (auto& prop : mProps) {
-            emulator::VehiclePropValue* protoVal = respMsg.add_value();
-            populateProtoVehiclePropValue(protoVal, prop.second->get());
-        }
-    }
-}
-
-void DefaultVehicleHal::doSetProperty(emulator::EmulatorMessage& rxMsg,
-                                      emulator::EmulatorMessage& respMsg) {
-    emulator::VehiclePropValue protoVal = rxMsg.value(0);
-    VehiclePropValue val;
-
-    respMsg.set_msg_type(emulator::SET_PROPERTY_RESP);
-
-    val.prop = protoVal.prop();
-    val.areaId = protoVal.area_id();
-    val.timestamp = elapsedRealtimeNano();
-
-    // Copy value data if it is set.  This automatically handles complex data types if needed.
-    if (protoVal.has_string_value()) {
-        val.value.stringValue = protoVal.string_value().c_str();
-    }
-
-    if (protoVal.has_bytes_value()) {
-        std::vector<uint8_t> tmp(protoVal.bytes_value().begin(), protoVal.bytes_value().end());
-        val.value.bytes = tmp;
-    }
-
-    if (protoVal.int32_values_size() > 0) {
-        std::vector<int32_t> int32Values = std::vector<int32_t>(protoVal.int32_values_size());
-        for (int i=0; i<protoVal.int32_values_size(); i++) {
-            int32Values[i] = protoVal.int32_values(i);
-        }
-        val.value.int32Values = int32Values;
-    }
-
-    if (protoVal.int64_values_size() > 0) {
-        std::vector<int64_t> int64Values = std::vector<int64_t>(protoVal.int64_values_size());
-        for (int i=0; i<protoVal.int64_values_size(); i++) {
-            int64Values[i] = protoVal.int64_values(i);
-        }
-        val.value.int64Values = int64Values;
-    }
-
-    if (protoVal.float_values_size() > 0) {
-        std::vector<float> floatValues = std::vector<float>(protoVal.float_values_size());
-        for (int i=0; i<protoVal.float_values_size(); i++) {
-            floatValues[i] = protoVal.float_values(i);
-        }
-        val.value.floatValues = floatValues;
-    }
-
-    if (updateProperty(val) == StatusCode::OK) {
-        // Send property up to VehicleHalManager via callback
-        auto& pool = *getValuePool();
-        VehiclePropValuePtr v = pool.obtain(val);
-
-        doHalEvent(std::move(v));
-        respMsg.set_status(emulator::RESULT_OK);
-    } else {
-        respMsg.set_status(emulator::ERROR_INVALID_PROPERTY);
-    }
-}
-
-// This function should only be called while mPropsMutex is locked.
-VehiclePropValue* DefaultVehicleHal::getVehiclePropValueLocked(int32_t propId, int32_t areaId) {
-    if (getPropArea(propId) == VehicleArea::GLOBAL) {
-        // In VehicleHal, global properties have areaId = -1.  We use 0.
-        areaId = 0;
-    }
-
-    auto prop = mProps.find(std::make_pair(propId, areaId));
-    if (prop != mProps.end()) {
-        return prop->second->get();
-    }
-    ALOGW("%s: Property not found:  propId = 0x%x, areaId = 0x%x", __func__, propId, areaId);
-    return nullptr;
-}
-
-void DefaultVehicleHal::parseRxProtoBuf(std::vector<uint8_t>& msg) {
-    emulator::EmulatorMessage rxMsg;
-    emulator::EmulatorMessage respMsg;
-
-    if (rxMsg.ParseFromArray(msg.data(), msg.size())) {
-        switch (rxMsg.msg_type()) {
-        case emulator::GET_CONFIG_CMD:
-            doGetConfig(rxMsg, respMsg);
-            break;
-        case emulator::GET_CONFIG_ALL_CMD:
-            doGetConfigAll(rxMsg, respMsg);
-            break;
-        case emulator::GET_PROPERTY_CMD:
-            doGetProperty(rxMsg, respMsg);
-            break;
-        case emulator::GET_PROPERTY_ALL_CMD:
-            doGetPropertyAll(rxMsg, respMsg);
-            break;
-        case emulator::SET_PROPERTY_CMD:
-            doSetProperty(rxMsg, respMsg);
-            break;
-        default:
-            ALOGW("%s: Unknown message received, type = %d", __func__, rxMsg.msg_type());
-            respMsg.set_status(emulator::ERROR_UNIMPLEMENTED_CMD);
-            break;
-        }
-
-        // Send the reply
-        txMsg(respMsg);
-    } else {
-        ALOGE("%s: ParseFromString() failed. msgSize=%d", __func__, static_cast<int>(msg.size()));
-    }
-}
-
-// Copies internal VehiclePropConfig data structure to protobuf VehiclePropConfig
-void DefaultVehicleHal::populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
-                                                   const VehiclePropConfig& cfg) {
-    protoCfg->set_prop(cfg.prop);
-    protoCfg->set_access(toInt(cfg.access));
-    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);
-    }
-
-    if (cfg.configString.size() > 0) {
-        protoCfg->set_config_string(cfg.configString.c_str(), cfg.configString.size());
-    }
-
-    // Populate the min/max values based on property type
-    switch (getPropType(cfg.prop)) {
-    case VehiclePropertyType::STRING:
-    case VehiclePropertyType::BOOLEAN:
-    case VehiclePropertyType::INT32_VEC:
-    case VehiclePropertyType::FLOAT_VEC:
-    case VehiclePropertyType::BYTES:
-    case VehiclePropertyType::COMPLEX:
-        // Do nothing.  These types don't have min/max values
-        break;
-    case VehiclePropertyType::INT64:
-        if (cfg.areaConfigs.size() > 0) {
-            emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
-            aCfg->set_min_int64_value(cfg.areaConfigs[0].minInt64Value);
-            aCfg->set_max_int64_value(cfg.areaConfigs[0].maxInt64Value);
-        }
-        break;
-    case VehiclePropertyType::FLOAT:
-        if (cfg.areaConfigs.size() > 0) {
-            emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
-            aCfg->set_min_float_value(cfg.areaConfigs[0].minFloatValue);
-            aCfg->set_max_float_value(cfg.areaConfigs[0].maxFloatValue);
-        }
-        break;
-    case VehiclePropertyType::INT32:
-        if (cfg.areaConfigs.size() > 0) {
-            emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
-            aCfg->set_min_int32_value(cfg.areaConfigs[0].minInt32Value);
-            aCfg->set_max_int32_value(cfg.areaConfigs[0].maxInt32Value);
-        }
-        break;
-    default:
-        ALOGW("%s: Unknown property type:  0x%x", __func__, toInt(getPropType(cfg.prop)));
-        break;
-    }
-
-    protoCfg->set_min_sample_rate(cfg.minSampleRate);
-    protoCfg->set_max_sample_rate(cfg.maxSampleRate);
-}
-
-// Copies internal VehiclePropValue data structure to protobuf VehiclePropValue
-void DefaultVehicleHal::populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
-                                                      const VehiclePropValue* val) {
-    protoVal->set_prop(val->prop);
-    protoVal->set_value_type(toInt(getPropType(val->prop)));
-    protoVal->set_timestamp(val->timestamp);
-    protoVal->set_area_id(val->areaId);
-
-    // Copy value data if it is set.
-    //  - for bytes and strings, this is indicated by size > 0
-    //  - for int32, int64, and float, copy the values if vectors have data
-    if (val->value.stringValue.size() > 0) {
-        protoVal->set_string_value(val->value.stringValue.c_str(), val->value.stringValue.size());
-    }
-
-    if (val->value.bytes.size() > 0) {
-        protoVal->set_bytes_value(val->value.bytes.data(), val->value.bytes.size());
-    }
-
-    for (auto& int32Value : val->value.int32Values) {
-        protoVal->add_int32_values(int32Value);
-    }
-
-    for (auto& int64Value : val->value.int64Values) {
-        protoVal->add_int64_values(int64Value);
-    }
-
-    for (auto& floatValue : val->value.floatValues) {
-        protoVal->add_float_values(floatValue);
-    }
-}
-
-void DefaultVehicleHal::rxMsg() {
-    int  numBytes = 0;
-
-    while (mExit == 0) {
-        std::vector<uint8_t> msg = mComm->read();
-
-        if (msg.size() > 0) {
-            // Received a message.
-            parseRxProtoBuf(msg);
-        } else {
-            // This happens when connection is closed
-            ALOGD("%s: numBytes=%d, msgSize=%d", __func__, numBytes,
-                  static_cast<int32_t>(msg.size()));
-            break;
-        }
-    }
-}
-
-void DefaultVehicleHal::rxThread() {
-    bool isEmulator = android::base::GetBoolProperty("ro.kernel.qemu", false);
-
-    if (isEmulator) {
-        // Initialize pipe to Emulator
-        mComm.reset(new PipeComm);
-    } else {
-        // Initialize socket over ADB
-        mComm.reset(new SocketComm);
-    }
-
-    int retVal = mComm->open();
-
-    if (retVal == 0) {
-        // Comms are properly opened
-        while (mExit == 0) {
-            retVal = mComm->connect();
-
-            if (retVal >= 0) {
-                rxMsg();
-            }
-
-            // Check every 100ms for a new connection
-            std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        }
-    }
-}
-
-// This function sets the default value of a property if we are interested in setting it.
-// TODO:  Co-locate the default values with the configuration structure, to make it easier to
-//          add new properties and their defaults.
-void DefaultVehicleHal::setDefaultValue(VehiclePropValue* prop) {
-    switch (prop->prop) {
-    case toInt(VehicleProperty::INFO_MAKE):
-        prop->value.stringValue = "Default Car";
-        break;
-    case toInt(VehicleProperty::PERF_VEHICLE_SPEED):
-        prop->value.floatValues[0] = 0;
-        break;
-    case toInt(VehicleProperty::CURRENT_GEAR):
-        prop->value.int32Values[0] = toInt(VehicleGear::GEAR_PARK);
-        break;
-    case toInt(VehicleProperty::PARKING_BRAKE_ON):
-        prop->value.int32Values[0] = 1;
-        break;
-    case toInt(VehicleProperty::FUEL_LEVEL_LOW):
-        prop->value.int32Values[0] = 0;
-        break;
-    case toInt(VehicleProperty::HVAC_POWER_ON):
-        prop->value.int32Values[0] = 1;
-        break;
-    case toInt(VehicleProperty::HVAC_DEFROSTER):
-        prop->value.int32Values[0] = 0;
-        break;
-    case toInt(VehicleProperty::HVAC_RECIRC_ON):
-        prop->value.int32Values[0] = 1;
-        break;
-    case toInt(VehicleProperty::HVAC_AC_ON):
-        prop->value.int32Values[0] = 1;
-        break;
-    case toInt(VehicleProperty::HVAC_AUTO_ON):
-        prop->value.int32Values[0] = 1;
-        break;
-    case toInt(VehicleProperty::HVAC_FAN_SPEED):
-        prop->value.int32Values[0] = 3;
-        break;
-    case toInt(VehicleProperty::HVAC_FAN_DIRECTION):
-        prop->value.int32Values[0] = toInt(VehicleHvacFanDirection::FACE);
-        break;
-    case toInt(VehicleProperty::HVAC_TEMPERATURE_SET):
-        prop->value.floatValues[0] = 16;
-        break;
-    case toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE):
-        prop->value.floatValues[0] = 25;
-        break;
-    case toInt(VehicleProperty::NIGHT_MODE):
-        prop->value.int32Values[0] = 0;
-        break;
-    case toInt(VehicleProperty::DRIVING_STATUS):
-        prop->value.int32Values[0] = toInt(VehicleDrivingStatus::UNRESTRICTED);
-        break;
-    case toInt(VehicleProperty::GEAR_SELECTION):
-        prop->value.int32Values[0] = toInt(VehicleGear::GEAR_PARK);
-        break;
-    case toInt(VehicleProperty::INFO_FUEL_CAPACITY):
-        prop->value.floatValues[0] = 123000.0f;  // In milliliters
-        break;
-    case toInt(VehicleProperty::ENGINE_OIL_TEMP):
-        prop->value.floatValues[0] = 101;
-        break;
-    case toInt(VehicleProperty::DISPLAY_BRIGHTNESS):
-        prop->value.int32Values[0] = 7;
-        break;
-    case toInt(VehicleProperty::IGNITION_STATE):
-        prop->value.int32Values[0] = toInt(VehicleIgnitionState::ON);
-        break;
-    default:
-        ALOGW("%s: propId=0x%x not found", __func__, prop->prop);
-        break;
-    }
-}
-
-// Transmit a reply back to the emulator
-void DefaultVehicleHal::txMsg(emulator::EmulatorMessage& txMsg) {
-    int numBytes = txMsg.ByteSize();
-    std::vector<uint8_t> msg(numBytes);
-
-    if (txMsg.SerializeToArray(msg.data(), msg.size())) {
-        int retVal = 0;
-
-        // Send the message
-        if (mExit == 0) {
-            mComm->write(msg);
-        }
-
-        if (retVal < 0) {
-            ALOGE("%s: Failed to tx message: retval=%d, errno=%d", __func__, retVal, errno);
-        }
-    } else {
-        ALOGE("%s: SerializeToString failed!", __func__);
-    }
-}
-
-// Updates the property value held in the HAL
-StatusCode DefaultVehicleHal::updateProperty(const VehiclePropValue& propValue) {
-    auto propId = propValue.prop;
-    auto areaId = propValue.areaId;
-    StatusCode status = StatusCode::INVALID_ARG;
-
-    {
-        std::lock_guard<std::mutex> lock(mPropsMutex);
-
-        VehiclePropValue* internalPropValue = getVehiclePropValueLocked(propId, areaId);
-        if (internalPropValue != nullptr) {
-            internalPropValue->value = propValue.value;
-            internalPropValue->timestamp = propValue.timestamp;
-            status = StatusCode::OK;
-        }
-    }
-    return status;
-}
-
-VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(
-        const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
-    auto areaId = requestedPropValue.areaId;
-    auto& pool = *getValuePool();
-    auto propId = requestedPropValue.prop;
-    StatusCode status;
-    VehiclePropValuePtr v = nullptr;
-
-    switch (propId) {
-    default:
-        {
-            std::lock_guard<std::mutex> lock(mPropsMutex);
-
-            VehiclePropValue *internalPropValue = getVehiclePropValueLocked(propId, areaId);
-            if (internalPropValue != nullptr) {
-                v = pool.obtain(*internalPropValue);
-            }
-        }
-
-        if (v != nullptr) {
-            status = StatusCode::OK;
-        } else {
-            status = StatusCode::INVALID_ARG;
-        }
-        break;
-    }
-
-    *outStatus = status;
-    return v;
-}
-
-StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) {
-    auto propId = propValue.prop;
-    StatusCode status;
-    switch (propId) {
-        default:
-            if (mHvacPowerProps.count(propId)) {
-                std::lock_guard<std::mutex> lock(mPropsMutex);
-                auto hvacPowerOn = getVehiclePropValueLocked(toInt(VehicleProperty::HVAC_POWER_ON),
-                                                             toInt(VehicleAreaZone::ROW_1));
-
-                if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1
-                        && hvacPowerOn->value.int32Values[0] == 0) {
-                    status = StatusCode::NOT_AVAILABLE;
-                    break;
-                }
-            }
-            status = updateProperty(propValue);
-            if (status == StatusCode::OK) {
-                // Send property update to emulator
-                emulator::EmulatorMessage msg;
-                emulator::VehiclePropValue *val = msg.add_value();
-                populateProtoVehiclePropValue(val, &propValue);
-                msg.set_status(emulator::RESULT_OK);
-                msg.set_msg_type(emulator::SET_PROPERTY_ASYNC);
-                txMsg(msg);
-            }
-            break;
-    }
-
-    return status;
-}
-
-V2_0::StatusCode DefaultVehicleHal::addCustomProperty(int32_t property,
-    std::unique_ptr<CustomVehiclePropertyHandler>&& handler) {
-    mProps[std::make_pair(property, 0)] = std::move(handler);
-    ALOGW("%s: Added custom property: propId = 0x%x", __func__, property);
-    return StatusCode::OK;
-}
-
-// Parse supported properties list and generate vector of property values to hold current values.
-void DefaultVehicleHal::onCreate() {
-    // Initialize member variables
-    mExit = 0;
-
-    for (auto& prop : kHvacPowerProperties) {
-        mHvacPowerProps.insert(prop);
-    }
-
-    // Get the list of configurations supported by this HAL
-    std::vector<VehiclePropConfig> configs = listProperties();
-
-    for (auto& cfg : configs) {
-        VehiclePropertyType propType = getPropType(cfg.prop);
-        int32_t supportedAreas = cfg.supportedAreas;
-        int32_t vecSize;
-
-        // Set the vector size based on property type
-        switch (propType) {
-        case VehiclePropertyType::BOOLEAN:
-        case VehiclePropertyType::INT32:
-        case VehiclePropertyType::INT64:
-        case VehiclePropertyType::FLOAT:
-            vecSize = 1;
-            break;
-        case VehiclePropertyType::INT32_VEC:
-        case VehiclePropertyType::FLOAT_VEC:
-        case VehiclePropertyType::BYTES:
-            // TODO:  Add proper support for these types
-            vecSize = 1;
-            break;
-        case VehiclePropertyType::STRING:
-            // Require individual handling
-            vecSize = 0;
-            break;
-        case VehiclePropertyType::COMPLEX:
-            switch (cfg.prop) {
-            default:
-                // Need to handle each complex property separately
-                break;
-            }
-            continue;
-        default:
-            ALOGE("%s: propType=0x%x not found", __func__, propType);
-            vecSize = 0;
-            break;
-        }
-
-        //  A global property will have supportedAreas = 0
-        if (getPropArea(cfg.prop) == VehicleArea::GLOBAL) {
-            supportedAreas = 0;
-        }
-
-        // This loop is a do-while so it executes at least once to handle global properties
-        do {
-            int32_t curArea = supportedAreas;
-
-            // Clear the right-most bit of supportedAreas
-            supportedAreas &= supportedAreas - 1;
-
-            // Set curArea to the previously cleared bit
-            curArea ^= supportedAreas;
-
-            // Create a separate instance for each individual zone
-            std::unique_ptr<VehiclePropValue> prop = createVehiclePropValue(propType, vecSize);
-            prop->areaId = curArea;
-            prop->prop = cfg.prop;
-            setDefaultValue(prop.get());
-            std::unique_ptr<CustomVehiclePropertyHandler> handler;
-            handler.reset(new StoredValueCustomVehiclePropertyHandler());
-            handler->set(*prop);
-            mProps[std::make_pair(prop->prop, prop->areaId)] =
-                    std::move(handler);
-        } while (supportedAreas != 0);
-    }
-
-    // Start rx thread
-    mThread = std::thread(&DefaultVehicleHal::rxThread, this);
-}
-
-void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
-    VehiclePropValuePtr v;
-
-    auto& pool = *getValuePool();
-
-    for (int32_t property : properties) {
-        if (isContinuousProperty(property)) {
-            // In real implementation this value should be read from sensor, random
-            // value used for testing purpose only.
-            std::lock_guard<std::mutex> lock(mPropsMutex);
-
-            VehiclePropValue *internalPropValue = getVehiclePropValueLocked(property);
-            if (internalPropValue != nullptr) {
-                v = pool.obtain(*internalPropValue);
-            }
-            if (VehiclePropertyType::FLOAT == getPropType(property)) {
-                // Just get some randomness to continuous properties to see slightly differnt values
-                // on the other end.
-                v->value.floatValues[0] = v->value.floatValues[0] + std::rand() % 5;
-            }
-        } else {
-            ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
-        }
-
-        if (v.get()) {
-            v->timestamp = elapsedRealtimeNano();
-            doHalEvent(std::move(v));
-        }
-    }
-}
-
-StatusCode DefaultVehicleHal::subscribe(int32_t property, int32_t,
-                                        float sampleRate) {
-    ALOGI("subscribe called for property: 0x%x, sampleRate: %f", property, sampleRate);
-
-    if (isContinuousProperty(property)) {
-        mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property);
-    }
-    return StatusCode::OK;
-}
-
-StatusCode DefaultVehicleHal::unsubscribe(int32_t property) {
-    ALOGI("%s propId: 0x%x", __func__, property);
-    if (isContinuousProperty(property)) {
-        mRecurrentTimer.unregisterRecurrentEvent(property);
-    }
-    return StatusCode::OK;
-}
-
-const VehiclePropConfig* DefaultVehicleHal::getPropConfig(int32_t propId) const {
-    auto it = mPropConfigMap.find(propId);
-    return it == mPropConfigMap.end() ? nullptr : it->second;
-}
-
-bool DefaultVehicleHal::isContinuousProperty(int32_t propId) const {
-    const VehiclePropConfig* config = getPropConfig(propId);
-    if (config == nullptr) {
-        ALOGW("Config not found for property: 0x%x", propId);
-        return false;
-    }
-    return config->changeMode == VehiclePropertyChangeMode::CONTINUOUS;
-}
-
-}  // impl
-
-}  // namespace V2_0
-}  // namespace vehicle
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
deleted file mode 100644
index c8310b3..0000000
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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 android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
-#define android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
-
-#include <map>
-#include <memory>
-#include <sys/socket.h>
-#include <thread>
-#include <unordered_set>
-
-#include <utils/SystemClock.h>
-
-#include "CommBase.h"
-#include "VehicleHalProto.pb.h"
-
-#include <vhal_v2_0/RecurrentTimer.h>
-#include <vhal_v2_0/VehicleHal.h>
-
-#include "DefaultConfig.h"
-#include "VehicleHalProto.pb.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_0 {
-
-namespace impl {
-
-class DefaultVehicleHal : public VehicleHal {
-public:
-    class CustomVehiclePropertyHandler {
-    public:
-        virtual VehiclePropValue* get() = 0;
-        virtual StatusCode set(const VehiclePropValue& propValue) = 0;
-        virtual ~CustomVehiclePropertyHandler() = default;
-    };
-
-protected:
-    class StoredValueCustomVehiclePropertyHandler :
-        public CustomVehiclePropertyHandler {
-    public:
-        VehiclePropValue* get() override {
-            return mPropValue.get();
-        }
-
-        StatusCode set(const VehiclePropValue& propValue) {
-            *mPropValue = propValue;
-            return StatusCode::OK;
-        }
-private:
-    std::unique_ptr<VehiclePropValue> mPropValue{new VehiclePropValue()};
-};
-
-public:
-  DefaultVehicleHal() : mRecurrentTimer(
-            std::bind(&DefaultVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)) {
-        for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
-            mPropConfigMap[kVehicleProperties[i].prop] = &kVehicleProperties[i];
-        }
-    }
-
-    ~DefaultVehicleHal() override {
-        // Notify thread to finish and wait for it to terminate
-        mExit = 1;
-
-        // Close emulator socket if it is open
-        mComm->stop();
-
-        mThread.join();
-    }
-
-    std::vector<VehiclePropConfig> listProperties() override {
-        return std::vector<VehiclePropConfig>(std::begin(kVehicleProperties),
-                                              std::end(kVehicleProperties));
-    }
-
-    VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
-                            StatusCode* outStatus) override;
-
-    void onCreate() override;
-
-    StatusCode set(const VehiclePropValue& propValue) override;
-
-    StatusCode subscribe(int32_t property, int32_t areas, float sampleRate) override;
-
-    StatusCode unsubscribe(int32_t property) override;
-
-    /**
-     * Add custom property information to this HAL instance.
-     *
-     * This is useful for allowing later versions of Vehicle HAL to coalesce
-     * the list of properties they support with a previous version of the HAL.
-     *
-     * @param property The identifier of the new property
-     * @param handler The object that will handle get/set requests
-     * @return OK on success, an error code on failure
-     */
-    virtual StatusCode addCustomProperty(int32_t,
-        std::unique_ptr<CustomVehiclePropertyHandler>&&);
-
-    /**
-     * Add custom property information to this HAL instance.
-     *
-     * This is useful for allowing later versions of Vehicle HAL to coalesce
-     * the list of properties they support with a previous version of the HAL.
-     *
-     * @param initialValue The initial value for the new property. This is not
-     *                     constant data, as later set() operations can change
-     *                     this value at will
-     * @return OK on success, an error code on failure
-     */
-    virtual StatusCode addCustomProperty(
-        const VehiclePropValue& initialValue) {
-        std::unique_ptr<CustomVehiclePropertyHandler> handler;
-        handler.reset(new StoredValueCustomVehiclePropertyHandler());
-        StatusCode setResponse = handler->set(initialValue);
-        if (StatusCode::OK == setResponse) {
-          return addCustomProperty(initialValue.prop,
-                                   std::move(handler));
-        } else {
-          return setResponse;
-        }
-    }
-
-private:
-    void doGetConfig(emulator::EmulatorMessage& rxMsg, emulator::EmulatorMessage& respMsg);
-    void doGetConfigAll(emulator::EmulatorMessage& rxMsg, emulator::EmulatorMessage& respMsg);
-    void doGetProperty(emulator::EmulatorMessage& rxMsg, emulator::EmulatorMessage& respMsg);
-    void doGetPropertyAll(emulator::EmulatorMessage& rxMsg, emulator::EmulatorMessage& respMsg);
-    void doSetProperty(emulator::EmulatorMessage& rxMsg, emulator::EmulatorMessage& respMsg);
-    VehiclePropValue* getVehiclePropValueLocked(int32_t propId, int32_t areaId = 0);
-    const VehiclePropConfig* getPropConfig(int32_t propId) const;
-    bool isContinuousProperty(int32_t propId) const;
-    void parseRxProtoBuf(std::vector<uint8_t>& msg);
-    void populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
-                                    const VehiclePropConfig& cfg);
-    void populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
-                                       const VehiclePropValue* val);
-    void setDefaultValue(VehiclePropValue* prop);
-    void rxMsg();
-    void rxThread();
-    void txMsg(emulator::EmulatorMessage& txMsg);
-    StatusCode updateProperty(const VehiclePropValue& propValue);
-
-    constexpr std::chrono::nanoseconds hertzToNanoseconds(float hz) const {
-        return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
-    }
-
-    void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
-
-private:
-    std::map<
-        std::pair<int32_t /*VehicleProperty*/, int32_t /*areaId*/>,
-        std::unique_ptr<CustomVehiclePropertyHandler>> mProps;
-    std::atomic<int> mExit;
-    std::unordered_set<int32_t> mHvacPowerProps;
-    std::mutex mPropsMutex;
-    std::thread mThread;
-    std::unique_ptr<CommBase> mComm{nullptr};
-    RecurrentTimer mRecurrentTimer;
-    std::unordered_map<int32_t, const VehiclePropConfig*> mPropConfigMap;
-};
-
-}  // impl
-
-}  // namespace V2_0
-}  // namespace vehicle
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
-
-
-#endif  // android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
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
new file mode 100644
index 0000000..0ac6ada
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "DefaultVehicleHal_v2_0"
+#include <android/log.h>
+
+#include "EmulatedVehicleHal.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore)
+    : mPropStore(propStore),
+      mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)),
+      mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer,
+                                  this, std::placeholders::_1)) {
+
+    for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
+        mPropStore->registerProperty(kVehicleProperties[i].config);
+    }
+}
+
+VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get(
+        const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
+    VehiclePropValuePtr v = nullptr;
+
+    auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue);
+    if (internalPropValue != nullptr) {
+        v = getValuePool()->obtain(*internalPropValue);
+    }
+
+    *outStatus = v != nullptr ? StatusCode::OK : StatusCode::INVALID_ARG;
+    return v;
+}
+
+StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) {
+    if (mHvacPowerProps.count(propValue.prop)) {
+        auto hvacPowerOn = mPropStore->readValueOrNull(toInt(VehicleProperty::HVAC_POWER_ON),
+                                                      toInt(VehicleAreaZone::ROW_1));
+
+        if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1
+                && hvacPowerOn->value.int32Values[0] == 0) {
+            return StatusCode::NOT_AVAILABLE;
+        }
+    }
+
+    if (!mPropStore->writeValue(propValue)) {
+        return StatusCode::INVALID_ARG;
+    }
+
+    getEmulatorOrDie()->doSetValueFromClient(propValue);
+
+    return StatusCode::OK;
+}
+
+// Parse supported properties list and generate vector of property values to hold current values.
+void EmulatedVehicleHal::onCreate() {
+    for (auto& it : kVehicleProperties) {
+        VehiclePropConfig cfg = it.config;
+        int32_t supportedAreas = cfg.supportedAreas;
+
+        //  A global property will have supportedAreas = 0
+        if (isGlobalProp(cfg.prop)) {
+            supportedAreas = 0;
+        }
+
+        // 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.
+
+            // 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()) {
+                    prop.value = valueForAreaIt->second;
+                } else {
+                    ALOGW("%s failed to get default value for prop 0x%x area 0x%x",
+                            __func__, cfg.prop, curArea);
+                }
+            } else {
+                prop.value = it.initialValue;
+            }
+            mPropStore->writeValue(prop);
+
+        } while (supportedAreas != 0);
+    }
+}
+
+std::vector<VehiclePropConfig> EmulatedVehicleHal::listProperties()  {
+    return mPropStore->getAllConfigs();
+}
+
+void EmulatedVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
+    VehiclePropValuePtr v;
+
+    auto& pool = *getValuePool();
+
+    for (int32_t property : properties) {
+        if (isContinuousProperty(property)) {
+            auto internalPropValue = mPropStore->readValueOrNull(property);
+            if (internalPropValue != nullptr) {
+                v = pool.obtain(*internalPropValue);
+            }
+        } else {
+            ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
+        }
+
+        if (v.get()) {
+            v->timestamp = elapsedRealtimeNano();
+            doHalEvent(std::move(v));
+        }
+    }
+}
+
+StatusCode EmulatedVehicleHal::subscribe(int32_t property, int32_t,
+                                        float sampleRate) {
+    ALOGI("%s propId: 0x%x, sampleRate: %f", __func__, property, sampleRate);
+
+    if (isContinuousProperty(property)) {
+        mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property);
+    }
+    return StatusCode::OK;
+}
+
+StatusCode EmulatedVehicleHal::unsubscribe(int32_t property) {
+    ALOGI("%s propId: 0x%x", __func__, property);
+    if (isContinuousProperty(property)) {
+        mRecurrentTimer.unregisterRecurrentEvent(property);
+    }
+    return StatusCode::OK;
+}
+
+bool EmulatedVehicleHal::isContinuousProperty(int32_t propId) const {
+    const VehiclePropConfig* config = mPropStore->getConfigOrNull(propId);
+    if (config == nullptr) {
+        ALOGW("Config not found for property: 0x%x", propId);
+        return false;
+    }
+    return config->changeMode == VehiclePropertyChangeMode::CONTINUOUS;
+}
+
+bool EmulatedVehicleHal::setPropertyFromVehicle(const VehiclePropValue& propValue) {
+    if (mPropStore->writeValue(propValue)) {
+        doHalEvent(getValuePool()->obtain(propValue));
+        return true;
+    } else {
+        return false;
+    }
+}
+
+std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const  {
+    return mPropStore->readAllValues();
+}
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
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
new file mode 100644
index 0000000..e0874e2
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -0,0 +1,88 @@
+/*
+ * 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 android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
+
+#include <map>
+#include <memory>
+#include <sys/socket.h>
+#include <thread>
+#include <unordered_set>
+
+#include <utils/SystemClock.h>
+
+#include "VehicleHalProto.pb.h"
+
+#include <vhal_v2_0/RecurrentTimer.h>
+#include <vhal_v2_0/VehicleHal.h>
+#include "vhal_v2_0/VehiclePropertyStore.h"
+
+#include "DefaultConfig.h"
+#include "VehicleHalProto.pb.h"
+#include "VehicleEmulator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+/** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */
+class EmulatedVehicleHal : public EmulatedVehicleHalIface {
+public:
+    EmulatedVehicleHal(VehiclePropertyStore* propStore);
+    ~EmulatedVehicleHal() = default;
+
+    //  Methods from VehicleHal
+    void onCreate() override;
+    std::vector<VehiclePropConfig> listProperties() override;
+    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 unsubscribe(int32_t property) override;
+
+    //  Methods from EmulatedVehicleHalIface
+    bool setPropertyFromVehicle(const VehiclePropValue& propValue) override;
+    std::vector<VehiclePropValue> getAllProperties() const override;
+
+private:
+    constexpr std::chrono::nanoseconds hertzToNanoseconds(float hz) const {
+        return std::chrono::nanoseconds(static_cast<int64_t>(1000000000L / hz));
+    }
+
+    void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
+    bool isContinuousProperty(int32_t propId) const;
+
+private:
+    VehiclePropertyStore* mPropStore;
+    std::unordered_set<int32_t> mHvacPowerProps;
+    RecurrentTimer mRecurrentTimer;
+};
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+
+#endif  // android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
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
new file mode 100644
index 0000000..38cb743
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.cpp
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "VehicleEmulator_v2_0"
+#include <android/log.h>
+
+#include <algorithm>
+#include <android-base/properties.h>
+#include <utils/SystemClock.h>
+
+#include <vhal_v2_0/VehicleUtils.h>
+
+#include "PipeComm.h"
+#include "SocketComm.h"
+
+#include "VehicleEmulator.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+std::unique_ptr<CommBase> CommFactory::create() {
+    bool isEmulator = android::base::GetBoolProperty("ro.kernel.qemu", false);
+
+    if (isEmulator) {
+        return std::make_unique<PipeComm>();
+    } else {
+        return std::make_unique<SocketComm>();
+    }
+}
+
+VehicleEmulator::~VehicleEmulator() {
+    mExit = true;   // Notify thread to finish and wait for it to terminate.
+    mComm->stop();  // Close emulator socket if it is open.
+    if (mThread.joinable()) mThread.join();
+}
+
+void VehicleEmulator::doSetValueFromClient(const VehiclePropValue& propValue) {
+    emulator::EmulatorMessage msg;
+    emulator::VehiclePropValue *val = msg.add_value();
+    populateProtoVehiclePropValue(val, &propValue);
+    msg.set_status(emulator::RESULT_OK);
+    msg.set_msg_type(emulator::SET_PROPERTY_ASYNC);
+    txMsg(msg);
+}
+
+void VehicleEmulator::doGetConfig(VehicleEmulator::EmulatorMessage& rxMsg,
+                                  VehicleEmulator::EmulatorMessage& respMsg) {
+    std::vector<VehiclePropConfig> configs = mHal->listProperties();
+    emulator::VehiclePropGet getProp = rxMsg.prop(0);
+
+    respMsg.set_msg_type(emulator::GET_CONFIG_RESP);
+    respMsg.set_status(emulator::ERROR_INVALID_PROPERTY);
+
+    for (auto& config : configs) {
+        // Find the config we are looking for
+        if (config.prop == getProp.prop()) {
+            emulator::VehiclePropConfig* protoCfg = respMsg.add_config();
+            populateProtoVehicleConfig(protoCfg, config);
+            respMsg.set_status(emulator::RESULT_OK);
+            break;
+        }
+    }
+}
+
+void VehicleEmulator::doGetConfigAll(VehicleEmulator::EmulatorMessage& /* rxMsg */,
+                                     VehicleEmulator::EmulatorMessage& respMsg) {
+    std::vector<VehiclePropConfig> configs = mHal->listProperties();
+
+    respMsg.set_msg_type(emulator::GET_CONFIG_ALL_RESP);
+    respMsg.set_status(emulator::RESULT_OK);
+
+    for (auto& config : configs) {
+        emulator::VehiclePropConfig* protoCfg = respMsg.add_config();
+        populateProtoVehicleConfig(protoCfg, config);
+    }
+}
+
+void VehicleEmulator::doGetProperty(VehicleEmulator::EmulatorMessage& rxMsg,
+                                    VehicleEmulator::EmulatorMessage& respMsg)  {
+    int32_t areaId = 0;
+    emulator::VehiclePropGet getProp = rxMsg.prop(0);
+    int32_t propId = getProp.prop();
+    emulator::Status status = emulator::ERROR_INVALID_PROPERTY;
+
+    respMsg.set_msg_type(emulator::GET_PROPERTY_RESP);
+
+    if (getProp.has_area_id()) {
+        areaId = getProp.area_id();
+    }
+
+    {
+        VehiclePropValue request = { .prop = propId, .areaId = areaId };
+        StatusCode halStatus;
+        auto val = mHal->get(request, &halStatus);
+        if (val != nullptr) {
+            emulator::VehiclePropValue* protoVal = respMsg.add_value();
+            populateProtoVehiclePropValue(protoVal, val.get());
+            status = emulator::RESULT_OK;
+        }
+    }
+
+    respMsg.set_status(status);
+}
+
+void VehicleEmulator::doGetPropertyAll(VehicleEmulator::EmulatorMessage& /* rxMsg */,
+                                       VehicleEmulator::EmulatorMessage& respMsg)  {
+    respMsg.set_msg_type(emulator::GET_PROPERTY_ALL_RESP);
+    respMsg.set_status(emulator::RESULT_OK);
+
+    {
+        for (const auto& prop : mHal->getAllProperties()) {
+            emulator::VehiclePropValue* protoVal = respMsg.add_value();
+            populateProtoVehiclePropValue(protoVal, &prop);
+        }
+    }
+}
+
+void VehicleEmulator::doSetProperty(VehicleEmulator::EmulatorMessage& rxMsg,
+                                    VehicleEmulator::EmulatorMessage& respMsg) {
+    emulator::VehiclePropValue protoVal = rxMsg.value(0);
+    VehiclePropValue val = {
+        .prop = protoVal.prop(),
+        .areaId = protoVal.area_id(),
+        .timestamp = elapsedRealtimeNano(),
+    };
+
+    respMsg.set_msg_type(emulator::SET_PROPERTY_RESP);
+
+    // Copy value data if it is set.  This automatically handles complex data types if needed.
+    if (protoVal.has_string_value()) {
+        val.value.stringValue = protoVal.string_value().c_str();
+    }
+
+    if (protoVal.has_bytes_value()) {
+        val.value.bytes = std::vector<uint8_t> { protoVal.bytes_value().begin(),
+                                                 protoVal.bytes_value().end() };
+    }
+
+    if (protoVal.int32_values_size() > 0) {
+        val.value.int32Values = std::vector<int32_t> { protoVal.int32_values().begin(),
+                                                       protoVal.int32_values().end() };
+    }
+
+    if (protoVal.int64_values_size() > 0) {
+        val.value.int64Values = std::vector<int64_t> { protoVal.int64_values().begin(),
+                                                       protoVal.int64_values().end() };
+    }
+
+    if (protoVal.float_values_size() > 0) {
+        val.value.floatValues = std::vector<float> { protoVal.float_values().begin(),
+                                                     protoVal.float_values().end() };
+    }
+
+    bool halRes = mHal->setPropertyFromVehicle(val);
+    respMsg.set_status(halRes ? emulator::RESULT_OK : emulator::ERROR_INVALID_PROPERTY);
+}
+
+void VehicleEmulator::txMsg(emulator::EmulatorMessage& txMsg) {
+    int numBytes = txMsg.ByteSize();
+    std::vector<uint8_t> msg(static_cast<size_t>(numBytes));
+
+    if (!txMsg.SerializeToArray(msg.data(), static_cast<int32_t>(msg.size()))) {
+        ALOGE("%s: SerializeToString failed!", __func__);
+        return;
+    }
+
+    if (mExit) {
+        ALOGW("%s: unable to transmit a message, connection closed", __func__);
+        return;
+    }
+
+    // Send the message
+    int retVal = mComm->write(msg);
+    if (retVal < 0) {
+        ALOGE("%s: Failed to tx message: retval=%d, errno=%d", __func__, retVal, errno);
+    }
+}
+
+void VehicleEmulator::parseRxProtoBuf(std::vector<uint8_t>& msg) {
+    emulator::EmulatorMessage rxMsg;
+    emulator::EmulatorMessage respMsg;
+
+    if (rxMsg.ParseFromArray(msg.data(), static_cast<int32_t>(msg.size()))) {
+        switch (rxMsg.msg_type()) {
+            case emulator::GET_CONFIG_CMD:
+                doGetConfig(rxMsg, respMsg);
+                break;
+            case emulator::GET_CONFIG_ALL_CMD:
+                doGetConfigAll(rxMsg, respMsg);
+                break;
+            case emulator::GET_PROPERTY_CMD:
+                doGetProperty(rxMsg, respMsg);
+                break;
+            case emulator::GET_PROPERTY_ALL_CMD:
+                doGetPropertyAll(rxMsg, respMsg);
+                break;
+            case emulator::SET_PROPERTY_CMD:
+                doSetProperty(rxMsg, respMsg);
+                break;
+            default:
+                ALOGW("%s: Unknown message received, type = %d", __func__, rxMsg.msg_type());
+                respMsg.set_status(emulator::ERROR_UNIMPLEMENTED_CMD);
+                break;
+        }
+
+        // Send the reply
+        txMsg(respMsg);
+    } else {
+        ALOGE("%s: ParseFromString() failed. msgSize=%d", __func__, static_cast<int>(msg.size()));
+    }
+}
+
+void VehicleEmulator::populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
+                                                 const VehiclePropConfig& cfg) {
+    protoCfg->set_prop(cfg.prop);
+    protoCfg->set_access(toInt(cfg.access));
+    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);
+    }
+
+    if (cfg.configString.size() > 0) {
+        protoCfg->set_config_string(cfg.configString.c_str(), cfg.configString.size());
+    }
+
+    // Populate the min/max values based on property type
+    switch (getPropType(cfg.prop)) {
+        case VehiclePropertyType::STRING:
+        case VehiclePropertyType::BOOLEAN:
+        case VehiclePropertyType::INT32_VEC:
+        case VehiclePropertyType::FLOAT_VEC:
+        case VehiclePropertyType::BYTES:
+        case VehiclePropertyType::COMPLEX:
+            // Do nothing.  These types don't have min/max values
+            break;
+        case VehiclePropertyType::INT64:
+            if (cfg.areaConfigs.size() > 0) {
+                emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
+                aCfg->set_min_int64_value(cfg.areaConfigs[0].minInt64Value);
+                aCfg->set_max_int64_value(cfg.areaConfigs[0].maxInt64Value);
+            }
+            break;
+        case VehiclePropertyType::FLOAT:
+            if (cfg.areaConfigs.size() > 0) {
+                emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
+                aCfg->set_min_float_value(cfg.areaConfigs[0].minFloatValue);
+                aCfg->set_max_float_value(cfg.areaConfigs[0].maxFloatValue);
+            }
+            break;
+        case VehiclePropertyType::INT32:
+            if (cfg.areaConfigs.size() > 0) {
+                emulator::VehicleAreaConfig* aCfg = protoCfg->add_area_configs();
+                aCfg->set_min_int32_value(cfg.areaConfigs[0].minInt32Value);
+                aCfg->set_max_int32_value(cfg.areaConfigs[0].maxInt32Value);
+            }
+            break;
+        default:
+            ALOGW("%s: Unknown property type:  0x%x", __func__, toInt(getPropType(cfg.prop)));
+            break;
+    }
+
+    protoCfg->set_min_sample_rate(cfg.minSampleRate);
+    protoCfg->set_max_sample_rate(cfg.maxSampleRate);
+}
+
+void VehicleEmulator::populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
+                                                    const VehiclePropValue* val) {
+    protoVal->set_prop(val->prop);
+    protoVal->set_value_type(toInt(getPropType(val->prop)));
+    protoVal->set_timestamp(val->timestamp);
+    protoVal->set_area_id(val->areaId);
+
+    // Copy value data if it is set.
+    //  - for bytes and strings, this is indicated by size > 0
+    //  - for int32, int64, and float, copy the values if vectors have data
+    if (val->value.stringValue.size() > 0) {
+        protoVal->set_string_value(val->value.stringValue.c_str(), val->value.stringValue.size());
+    }
+
+    if (val->value.bytes.size() > 0) {
+        protoVal->set_bytes_value(val->value.bytes.data(), val->value.bytes.size());
+    }
+
+    for (auto& int32Value : val->value.int32Values) {
+        protoVal->add_int32_values(int32Value);
+    }
+
+    for (auto& int64Value : val->value.int64Values) {
+        protoVal->add_int64_values(int64Value);
+    }
+
+    for (auto& floatValue : val->value.floatValues) {
+        protoVal->add_float_values(floatValue);
+    }
+}
+
+void VehicleEmulator::rxMsg() {
+    while (!mExit) {
+        std::vector<uint8_t> msg = mComm->read();
+
+        if (msg.size() > 0) {
+            // Received a message.
+            parseRxProtoBuf(msg);
+        } else {
+            // This happens when connection is closed
+            ALOGD("%s: msgSize=%zu", __func__, msg.size());
+            break;
+        }
+    }
+}
+
+void VehicleEmulator::rxThread() {
+    if (mExit) return;
+
+    int retVal = mComm->open();
+    if (retVal != 0) mExit = true;
+
+    // Comms are properly opened
+    while (!mExit) {
+        retVal = mComm->connect();
+
+        if (retVal >= 0) {
+            rxMsg();
+        }
+
+        // Check every 100ms for a new connection
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    }
+}
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
new file mode 100644
index 0000000..9a75ddc
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleEmulator.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 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 android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
+
+#include <memory>
+#include <thread>
+#include <vector>
+#include "vhal_v2_0/VehicleHal.h"
+
+#include "CommBase.h"
+#include "VehicleHalProto.pb.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+class VehicleEmulator;  // Forward declaration.
+
+/** Extension of VehicleHal that used by VehicleEmulator. */
+class EmulatedVehicleHalIface : public VehicleHal {
+public:
+    virtual bool setPropertyFromVehicle(const VehiclePropValue& propValue) = 0;
+    virtual std::vector<VehiclePropValue> getAllProperties() const = 0;
+
+    void registerEmulator(VehicleEmulator* emulator) {
+        ALOGI("%s, emulator: %p", __func__, emulator);
+        std::lock_guard<std::mutex> g(mEmulatorLock);
+        mEmulator = emulator;
+    }
+
+protected:
+    VehicleEmulator* getEmulatorOrDie() {
+        std::lock_guard<std::mutex> g(mEmulatorLock);
+        ALOGI("%s, emulator: %p", __func__, mEmulator);
+        assert(mEmulator != nullptr);
+        return mEmulator;
+    }
+
+private:
+    mutable std::mutex mEmulatorLock;
+    VehicleEmulator* mEmulator;
+};
+
+struct CommFactory {
+    static std::unique_ptr<CommBase> create();
+};
+
+/**
+ * Emulates vehicle by providing controlling interface from host side either through ADB or Pipe.
+ */
+class VehicleEmulator {
+public:
+    VehicleEmulator(EmulatedVehicleHalIface* hal,
+                    std::unique_ptr<CommBase> comm = CommFactory::create())
+            : mHal { hal },
+              mComm(comm.release()),
+              mThread { &VehicleEmulator::rxThread, this} {
+        mHal->registerEmulator(this);
+    }
+    virtual ~VehicleEmulator();
+
+    void doSetValueFromClient(const VehiclePropValue& propValue);
+
+private:
+    using EmulatorMessage = emulator::EmulatorMessage;
+
+    void doGetConfig(EmulatorMessage& rxMsg, EmulatorMessage& respMsg);
+    void doGetConfigAll(EmulatorMessage& rxMsg, EmulatorMessage& respMsg);
+    void doGetProperty(EmulatorMessage& rxMsg, EmulatorMessage& respMsg);
+    void doGetPropertyAll(EmulatorMessage& rxMsg, EmulatorMessage& respMsg);
+    void doSetProperty(EmulatorMessage& rxMsg, EmulatorMessage& respMsg);
+    void txMsg(emulator::EmulatorMessage& txMsg);
+    void parseRxProtoBuf(std::vector<uint8_t>& msg);
+    void populateProtoVehicleConfig(emulator::VehiclePropConfig* protoCfg,
+                                    const VehiclePropConfig& cfg);
+    void populateProtoVehiclePropValue(emulator::VehiclePropValue* protoVal,
+                                       const VehiclePropValue* val);
+    void rxMsg();
+    void rxThread();
+
+private:
+    std::atomic<bool> mExit { false };
+    EmulatedVehicleHalIface* mHal;
+    std::unique_ptr<CommBase> mComm;
+    std::thread mThread;
+};
+
+}  // impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif // android_hardware_automotive_vehicle_V2_0_impl_VehicleHalEmulator_H_
diff --git a/automotive/vehicle/2.1/default/Android.mk b/automotive/vehicle/2.1/default/Android.mk
index 51cb146..32ec456 100644
--- a/automotive/vehicle/2.1/default/Android.mk
+++ b/automotive/vehicle/2.1/default/Android.mk
@@ -49,7 +49,7 @@
 
 LOCAL_MODULE:= $(vhal_v2_1)-default-impl-lib
 LOCAL_SRC_FILES:= \
-    impl/vhal_v2_1/DefaultVehicleHal.cpp \
+    impl/vhal_v2_1/EmulatedVehicleHal.cpp \
 
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/impl/vhal_v2_1 \
diff --git a/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h b/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h
index 945e3e0..6c44626 100644
--- a/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h
+++ b/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h
@@ -55,8 +55,7 @@
     const std::vector<uint8_t>& getSensorsBitmask() const;
 
     // Given a stringValue, fill in a VehiclePropValue
-    void fillPropValue(V2_0::VehiclePropValue *propValue,
-            std::string dtc) const;
+    void fillPropValue(const std::string& dtc, V2_0::VehiclePropValue *propValue) const;
 
 private:
     class BitmaskInVector {
diff --git a/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp b/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp
index b07717b..f4c63a9 100644
--- a/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp
+++ b/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp
@@ -99,8 +99,8 @@
     return mSensorsBitmask.getBitmask();
 }
 
-void Obd2SensorStore::fillPropValue(V2_0::VehiclePropValue *propValue,
-                                    std::string dtc) const {
+void Obd2SensorStore::fillPropValue(const std::string& dtc,
+                                    V2_0::VehiclePropValue *propValue) const {
     propValue->timestamp = elapsedRealtimeNano();
     propValue->value.int32Values = getIntegerSensors();
     propValue->value.floatValues = getFloatSensors();
diff --git a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h b/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h
index 6bdec59..aa9aa3c 100644
--- a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h
+++ b/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h
@@ -28,41 +28,50 @@
 
 namespace impl {
 
+// Some handy constants to avoid conversions from enum to int.
+constexpr int OBD2_LIVE_FRAME = (int) V2_1::VehicleProperty::OBD2_LIVE_FRAME;
+constexpr int OBD2_FREEZE_FRAME = (int) V2_1::VehicleProperty::OBD2_FREEZE_FRAME;
+constexpr int OBD2_FREEZE_FRAME_INFO = (int) V2_1::VehicleProperty::OBD2_FREEZE_FRAME_INFO;
+constexpr int OBD2_FREEZE_FRAME_CLEAR = (int) V2_1::VehicleProperty::OBD2_FREEZE_FRAME_CLEAR;
+constexpr int VEHICLE_MAP_SERVICE = (int) V2_1::VehicleProperty::VEHICLE_MAP_SERVICE;
+constexpr int WHEEL_TICK = (int) V2_1::VehicleProperty::WHEEL_TICK;
+
+
 const V2_0::VehiclePropConfig kVehicleProperties[] = {
     {
-        .prop = V2_0::toInt(V2_1::VehicleProperty::WHEEL_TICK),
+        .prop = WHEEL_TICK,
         .access = V2_0::VehiclePropertyAccess::READ,
         .changeMode = V2_0::VehiclePropertyChangeMode::CONTINUOUS,
     },
 
     {
-        .prop = V2_0::toInt(V2_1::VehicleProperty::OBD2_LIVE_FRAME),
+        .prop = OBD2_LIVE_FRAME,
         .access = V2_0::VehiclePropertyAccess::READ,
         .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE,
         .configArray = {0,0}
     },
 
     {
-        .prop = V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME),
+        .prop = OBD2_FREEZE_FRAME,
         .access = V2_0::VehiclePropertyAccess::READ,
         .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE,
         .configArray = {0,0}
     },
 
     {
-        .prop = V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME_INFO),
+        .prop = OBD2_FREEZE_FRAME_INFO,
         .access = V2_0::VehiclePropertyAccess::READ,
         .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE
     },
 
     {
-        .prop = V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME_CLEAR),
+        .prop = OBD2_FREEZE_FRAME_CLEAR,
         .access = V2_0::VehiclePropertyAccess::WRITE,
         .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE
     },
 
     {
-        .prop = V2_0::toInt(VehicleProperty::VEHICLE_MAP_SERVICE),
+        .prop = VEHICLE_MAP_SERVICE,
         .access = V2_0::VehiclePropertyAccess::READ_WRITE,
         .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE
     }
diff --git a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultVehicleHal.h b/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultVehicleHal.h
deleted file mode 100644
index af21138..0000000
--- a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultVehicleHal.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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 android_hardware_automotive_vehicle_V2_1_impl_DefaultVehicleHal_H_
-#define android_hardware_automotive_vehicle_V2_1_impl_DefaultVehicleHal_H_
-
-#include <memory>
-
-#include <utils/SystemClock.h>
-
-#include <vhal_v2_0/VehicleHal.h>
-#include <vhal_v2_0/DefaultVehicleHal.h>
-#include <vhal_v2_1/Obd2SensorStore.h>
-
-#include "DefaultConfig.h"
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-namespace V2_1 {
-
-namespace impl {
-
-using namespace std::placeholders;
-
-class DefaultVehicleHal : public V2_0::VehicleHal {
-public:
-    DefaultVehicleHal(V2_0::impl::DefaultVehicleHal* vhal20) :
-          mVehicleHal20(vhal20) {}
-
-    std::vector<V2_0::VehiclePropConfig> listProperties() override {
-        std::vector<V2_0::VehiclePropConfig> propConfigs(mVehicleHal20->listProperties());
-
-        // Join Vehicle Hal 2.0 and 2.1 configs.
-        propConfigs.insert(propConfigs.end(),
-                           std::begin(kVehicleProperties),
-                           std::end(kVehicleProperties));
-
-        return propConfigs;
-    }
-
-    VehiclePropValuePtr get(const V2_0::VehiclePropValue& requestedPropValue,
-                            V2_0::StatusCode* outStatus) override;
-
-    V2_0::StatusCode set(const V2_0::VehiclePropValue& propValue) override;
-
-    V2_0::StatusCode subscribe(int32_t property,
-                               int32_t areas,
-                               float sampleRate) override {
-        return mVehicleHal20->subscribe(property, areas, sampleRate);
-    }
-
-    V2_0::StatusCode unsubscribe(int32_t property) override {
-        return mVehicleHal20->unsubscribe(property);
-    }
-
-    void onCreate() override;
-
-private:
-    void initObd2LiveFrame(V2_0::VehiclePropConfig& propConfig,
-        V2_0::VehiclePropValue* liveObd2Frame);
-    void initObd2FreezeFrame(V2_0::VehiclePropConfig& propConfig);
-    V2_0::StatusCode fillObd2FreezeFrame(const V2_0::VehiclePropValue& requestedPropValue,
-            V2_0::VehiclePropValue* v);
-    V2_0::StatusCode fillObd2DtcInfo(V2_0::VehiclePropValue *v);
-    V2_0::StatusCode clearObd2FreezeFrames(const V2_0::VehiclePropValue& propValue);
-
-private:
-    V2_0::impl::DefaultVehicleHal* mVehicleHal20;
-    std::vector<std::unique_ptr<V2_0::VehiclePropValue>> mFreezeObd2Frames;
-};
-
-}  // impl
-
-}  // namespace V2_1
-}  // namespace vehicle
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
-
-
-#endif  // android_hardware_automotive_vehicle_V2_0_impl_DefaultVehicleHal_H_
diff --git a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultVehicleHal.cpp b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
similarity index 63%
rename from automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultVehicleHal.cpp
rename to automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
index b147ce7..ae7f416 100644
--- a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
@@ -21,7 +21,7 @@
 #include <netinet/in.h>
 #include <sys/socket.h>
 
-#include "DefaultVehicleHal.h"
+#include "EmulatedVehicleHal.h"
 #include "VehicleHalProto.pb.h"
 
 #define DEBUG_SOCKET    (33452)
@@ -120,118 +120,103 @@
     return sensorStore;
 }
 
-void DefaultVehicleHal::initObd2LiveFrame(V2_0::VehiclePropConfig& propConfig,
-    V2_0::VehiclePropValue* liveObd2Frame) {
-    auto sensorStore = fillDefaultObd2Frame(propConfig.configArray[0],
-            propConfig.configArray[1]);
-    sensorStore->fillPropValue(liveObd2Frame, "");
-    liveObd2Frame->prop = V2_0::toInt(VehicleProperty::OBD2_LIVE_FRAME);
+void EmulatedVehicleHal::initObd2LiveFrame(const V2_0::VehiclePropConfig& propConfig) {
+    auto liveObd2Frame = createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX, 0);
+    auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
+                                            static_cast<size_t>(propConfig.configArray[1]));
+    sensorStore->fillPropValue("", liveObd2Frame.get());
+    liveObd2Frame->prop = OBD2_LIVE_FRAME;
+
+    mPropStore->writeValue(*liveObd2Frame);
 }
 
-void DefaultVehicleHal::initObd2FreezeFrame(V2_0::VehiclePropConfig& propConfig) {
-    auto sensorStore = fillDefaultObd2Frame(propConfig.configArray[0],
-            propConfig.configArray[1]);
+void EmulatedVehicleHal::initObd2FreezeFrame(const V2_0::VehiclePropConfig& propConfig) {
+    auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
+                                            static_cast<size_t>(propConfig.configArray[1]));
 
-    mFreezeObd2Frames.push_back(
-            createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX,0));
-    mFreezeObd2Frames.push_back(
-            createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX,0));
-    mFreezeObd2Frames.push_back(
-            createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX,0));
-
-    sensorStore->fillPropValue(mFreezeObd2Frames[0].get(), "P0070");
-    sensorStore->fillPropValue(mFreezeObd2Frames[1].get(), "P0102");
-    sensorStore->fillPropValue(mFreezeObd2Frames[2].get(), "P0123");
+    static std::vector<std::string> sampleDtcs = { "P0070", "P0102" "P0123" };
+    for (auto&& dtc : sampleDtcs) {
+        auto freezeFrame = createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX, 0);
+        sensorStore->fillPropValue(dtc, freezeFrame.get());
+        mPropStore->writeValue(*freezeFrame);
+    }
 }
 
-template<typename Iterable>
-typename Iterable::const_iterator findPropValueAtTimestamp(
-        const Iterable& frames,
-        int64_t timestamp) {
-    return std::find_if(frames.begin(),
-            frames.end(),
-            [timestamp] (const std::unique_ptr<V2_0::VehiclePropValue>&
-                         propValue) -> bool {
-                             return propValue->timestamp == timestamp;
-            });
-}
-
-V2_0::StatusCode DefaultVehicleHal::fillObd2FreezeFrame(
+V2_0::StatusCode EmulatedVehicleHal::fillObd2FreezeFrame(
         const V2_0::VehiclePropValue& requestedPropValue,
-        V2_0::VehiclePropValue* v) {
+        V2_0::VehiclePropValue* outValue) {
     if (requestedPropValue.value.int64Values.size() != 1) {
         ALOGE("asked for OBD2_FREEZE_FRAME without valid timestamp");
         return V2_0::StatusCode::INVALID_ARG;
     }
     auto timestamp = requestedPropValue.value.int64Values[0];
-    auto freezeFrameIter = findPropValueAtTimestamp(mFreezeObd2Frames,
-            timestamp);
-    if(mFreezeObd2Frames.end() == freezeFrameIter) {
+    auto freezeFrame = mPropStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
+    if(freezeFrame == nullptr) {
         ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
         return V2_0::StatusCode::INVALID_ARG;
     }
-    const auto& freezeFrame = *freezeFrameIter;
-    v->prop = V2_0::toInt(VehicleProperty::OBD2_FREEZE_FRAME);
-    v->value.int32Values = freezeFrame->value.int32Values;
-    v->value.floatValues = freezeFrame->value.floatValues;
-    v->value.bytes = freezeFrame->value.bytes;
-    v->value.stringValue = freezeFrame->value.stringValue;
-    v->timestamp = freezeFrame->timestamp;
+    outValue->prop = OBD2_FREEZE_FRAME;
+    outValue->value.int32Values = freezeFrame->value.int32Values;
+    outValue->value.floatValues = freezeFrame->value.floatValues;
+    outValue->value.bytes = freezeFrame->value.bytes;
+    outValue->value.stringValue = freezeFrame->value.stringValue;
+    outValue->timestamp = freezeFrame->timestamp;
     return V2_0::StatusCode::OK;
 }
 
-V2_0::StatusCode DefaultVehicleHal::clearObd2FreezeFrames(
-    const V2_0::VehiclePropValue& propValue) {
+V2_0::StatusCode EmulatedVehicleHal::clearObd2FreezeFrames(const V2_0::VehiclePropValue& propValue) {
     if (propValue.value.int64Values.size() == 0) {
-        mFreezeObd2Frames.clear();
+        mPropStore->removeValuesForProperty(OBD2_FREEZE_FRAME);
         return V2_0::StatusCode::OK;
     } else {
         for(int64_t timestamp: propValue.value.int64Values) {
-            auto freezeFrameIter = findPropValueAtTimestamp(mFreezeObd2Frames,
-                    timestamp);
-            if(mFreezeObd2Frames.end() == freezeFrameIter) {
+            auto freezeFrame = mPropStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
+            if(freezeFrame == nullptr) {
                 ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
                 return V2_0::StatusCode::INVALID_ARG;
             }
-            mFreezeObd2Frames.erase(freezeFrameIter);
+            mPropStore->removeValue(*freezeFrame);
         }
     }
     return V2_0::StatusCode::OK;
 }
 
-V2_0::StatusCode DefaultVehicleHal::fillObd2DtcInfo(V2_0::VehiclePropValue* v) {
+V2_0::StatusCode EmulatedVehicleHal::fillObd2DtcInfo(V2_0::VehiclePropValue* outValue) {
     std::vector<int64_t> timestamps;
-    for(const auto& freezeFrame: mFreezeObd2Frames) {
-        timestamps.push_back(freezeFrame->timestamp);
+    for(const auto& freezeFrame: mPropStore->readValuesForProperty(OBD2_FREEZE_FRAME)) {
+        timestamps.push_back(freezeFrame.timestamp);
     }
-    v->value.int64Values = timestamps;
+    outValue->value.int64Values = timestamps;
     return V2_0::StatusCode::OK;
 }
 
-void DefaultVehicleHal::onCreate() {
-    mVehicleHal20->init(getValuePool(),
-                        std::bind(&DefaultVehicleHal::doHalEvent, this, _1),
-                        std::bind(&DefaultVehicleHal::doHalPropertySetError, this, _1, _2, _3));
+void EmulatedVehicleHal::onCreate() {
+    V2_0::impl::EmulatedVehicleHal::onCreate();
 
-    std::vector<V2_0::VehiclePropConfig> configs = listProperties();
-    for (auto& cfg : configs) {
-        switch(cfg.prop) {
-            case V2_0::toInt(V2_1::VehicleProperty::OBD2_LIVE_FRAME): {
-                auto liveObd2Frame = createVehiclePropValue(V2_0::VehiclePropertyType::COMPLEX, 0);
-                initObd2LiveFrame(cfg, liveObd2Frame.get());
-                mVehicleHal20->addCustomProperty(*liveObd2Frame);
+    initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
+    initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
+}
+
+void EmulatedVehicleHal::initStaticConfig() {
+    for (auto&& cfg = std::begin(kVehicleProperties); cfg != std::end(kVehicleProperties); ++cfg) {
+        V2_0::VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
+
+        switch (cfg->prop) {
+            case OBD2_FREEZE_FRAME: {
+                tokenFunction = [] (const V2_0::VehiclePropValue& propValue) {
+                    return propValue.timestamp;
+                };
+                break;
             }
-                break;
-            case V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME):
-                initObd2FreezeFrame(cfg);
-                break;
             default:
                 break;
         }
+
+        mPropStore->registerProperty(*cfg, tokenFunction);
     }
 }
 
-DefaultVehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(
+EmulatedVehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get(
         const V2_0::VehiclePropValue& requestedPropValue,
         V2_0::StatusCode* outStatus) {
 
@@ -240,34 +225,30 @@
     auto& pool = *getValuePool();
 
     switch (propId) {
-    case V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME):
+    case OBD2_FREEZE_FRAME:
         v = pool.obtainComplex();
         *outStatus = fillObd2FreezeFrame(requestedPropValue, v.get());
         return v;
-    case V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME_INFO):
+    case OBD2_FREEZE_FRAME_INFO:
         v = pool.obtainComplex();
         *outStatus = fillObd2DtcInfo(v.get());
         return v;
     default:
-        return mVehicleHal20->get(requestedPropValue, outStatus);
+        return V2_0::impl::EmulatedVehicleHal::get(requestedPropValue, outStatus);
     }
 }
 
-V2_0::StatusCode DefaultVehicleHal::set(
-        const V2_0::VehiclePropValue& propValue) {
-
+V2_0::StatusCode EmulatedVehicleHal::set(const V2_0::VehiclePropValue& propValue) {
     auto propId = propValue.prop;
     switch (propId) {
-    case V2_0::toInt(V2_1::VehicleProperty::OBD2_FREEZE_FRAME_CLEAR):
+    case OBD2_FREEZE_FRAME_CLEAR:
         return clearObd2FreezeFrames(propValue);
-        break;
-    case V2_0::toInt(V2_1::VehicleProperty::VEHICLE_MAP_SERVICE):
+    case VEHICLE_MAP_SERVICE:
         // Placeholder for future implementation of VMS property in the default hal. For now, just
         // returns OK; otherwise, hal clients crash with property not supported.
         return V2_0::StatusCode::OK;
-        break;
     default:
-        return mVehicleHal20->set(propValue);
+        return V2_0::impl::EmulatedVehicleHal::set(propValue);
     }
 }
 
diff --git a/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.h b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.h
new file mode 100644
index 0000000..7cc3b79
--- /dev/null
+++ b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.h
@@ -0,0 +1,77 @@
+/*
+ * 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 android_hardware_automotive_vehicle_V2_1_impl_EmulatedVehicleHal_H_
+#define android_hardware_automotive_vehicle_V2_1_impl_EmulatedVehicleHal_H_
+
+#include <memory>
+
+#include <utils/SystemClock.h>
+
+#include <vhal_v2_0/EmulatedVehicleHal.h>
+#include <vhal_v2_0/VehicleHal.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+#include <vhal_v2_1/Obd2SensorStore.h>
+
+#include "DefaultConfig.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_1 {
+
+namespace impl {
+
+using namespace std::placeholders;
+
+class EmulatedVehicleHal : public V2_0::impl::EmulatedVehicleHal {
+public:
+    EmulatedVehicleHal(V2_0::VehiclePropertyStore* propStore)
+        : V2_0::impl::EmulatedVehicleHal(propStore), mPropStore(propStore) {
+        initStaticConfig();
+    }
+
+    VehiclePropValuePtr get(const V2_0::VehiclePropValue& requestedPropValue,
+                            V2_0::StatusCode* outStatus) override;
+
+    V2_0::StatusCode set(const V2_0::VehiclePropValue& propValue) override;
+
+    void onCreate() override;
+
+private:
+    void initStaticConfig();
+    void initObd2LiveFrame(const V2_0::VehiclePropConfig& propConfig);
+    void initObd2FreezeFrame(const V2_0::VehiclePropConfig& propConfig);
+    V2_0::StatusCode fillObd2FreezeFrame(const V2_0::VehiclePropValue& requestedPropValue,
+                                        V2_0::VehiclePropValue* outValue);
+    V2_0::StatusCode fillObd2DtcInfo(V2_0::VehiclePropValue *outValue);
+    V2_0::StatusCode clearObd2FreezeFrames(const V2_0::VehiclePropValue& propValue);
+
+private:
+    V2_0::VehiclePropertyStore* mPropStore;
+};
+
+}  // impl
+
+}  // namespace V2_1
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+
+#endif  // android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleHal_H_
diff --git a/automotive/vehicle/2.1/default/service.cpp b/automotive/vehicle/2.1/default/service.cpp
index 0844622..4873279 100644
--- a/automotive/vehicle/2.1/default/service.cpp
+++ b/automotive/vehicle/2.1/default/service.cpp
@@ -23,9 +23,10 @@
 #include <android/hardware/automotive/vehicle/2.1/IVehicle.h>
 
 #include <vhal_v2_0/VehicleHalManager.h>
-#include <vhal_v2_0/DefaultVehicleHal.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+#include <vhal_v2_0/EmulatedVehicleHal.h>
 
-#include <vhal_v2_1/DefaultVehicleHal.h>
+#include <vhal_v2_1/EmulatedVehicleHal.h>
 
 using namespace android;
 using namespace android::hardware;
@@ -80,10 +81,10 @@
 };
 
 int main(int /* argc */, char* /* argv */ []) {
-    auto halImpl20 = std::make_unique<V2_0::impl::DefaultVehicleHal>();
-    auto halImpl21 = std::make_unique<V2_1::impl::DefaultVehicleHal>(halImpl20.get());
-
-    auto vehicleManager = std::make_unique<V2_0::VehicleHalManager>(halImpl21.get());
+    auto store = std::make_unique<V2_0::VehiclePropertyStore>();
+    auto hal = std::make_unique<V2_1::impl::EmulatedVehicleHal>(store.get());
+    auto emulator = std::make_unique<V2_0::impl::VehicleEmulator>(hal.get());
+    auto vehicleManager = std::make_unique<V2_0::VehicleHalManager>(hal.get());
 
     Vehicle_V2_1 vehicle21(vehicleManager.get());
 
diff --git a/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
index 8545d2f..0f76c39 100644
--- a/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
+++ b/bluetooth/1.0/default/android.hardware.bluetooth@1.0-service.rc
@@ -2,3 +2,4 @@
     class hal
     user bluetooth
     group bluetooth
+    writepid /dev/stune/foreground/tasks
diff --git a/camera/device/1.0/ICameraDevicePreviewCallback.hal b/camera/device/1.0/ICameraDevicePreviewCallback.hal
index e772301..4c9b517 100644
--- a/camera/device/1.0/ICameraDevicePreviewCallback.hal
+++ b/camera/device/1.0/ICameraDevicePreviewCallback.hal
@@ -17,6 +17,7 @@
 package android.hardware.camera.device@1.0;
 
 import android.hardware.camera.common@1.0::types;
+import android.hardware.graphics.allocator@2.0::types;
 import android.hardware.graphics.common@1.0::types;
 
 /**
@@ -88,7 +89,7 @@
      *
      * @return Status The status code for this operation.
      */
-    setUsage(ProducerUsageFlags usage) generates (Status status);
+    setUsage(ProducerUsage usage) generates (Status status);
 
     /**
      * Set the expected buffering mode for the preview output.
diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp
index a2fd0b0..af94b0f 100644
--- a/camera/device/1.0/default/Android.bp
+++ b/camera/device/1.0/default/Android.bp
@@ -7,6 +7,7 @@
     ],
     shared_libs: [
         "libhidlbase",
+        "libhidlmemory",
         "libhidltransport",
         "libhwbinder",
         "libutils",
@@ -14,16 +15,17 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
+        "android.hidl.allocator@1.0",
         "android.hidl.base@1.0",
+        "android.hidl.memory@1.0",
         "libcutils",
         "liblog",
         "libhardware",
         "libcamera_metadata",
-        "libbinder",
     ],
     static_libs: [
-        "android.hardware.camera.common@1.0-helper",
-        "libgrallocusage"
+        "android.hardware.camera.common@1.0-helper"
     ],
     export_include_dirs: ["."]
 }
+
diff --git a/camera/device/1.0/default/CameraDevice.cpp b/camera/device/1.0/default/CameraDevice.cpp
index 5e3fcf2..877c6e7 100644
--- a/camera/device/1.0/default/CameraDevice.cpp
+++ b/camera/device/1.0/default/CameraDevice.cpp
@@ -18,10 +18,9 @@
 #include <utils/Log.h>
 #include <hardware/camera.h>
 #include <hardware/gralloc1.h>
+#include <hidlmemory/mapping.h>
 #include <utils/Trace.h>
 
-#include <grallocusage/GrallocUsageConversion.h>
-
 #include "CameraDevice_1_0.h"
 
 namespace android {
@@ -31,6 +30,7 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
 
 HandleImporter& CameraDevice::sHandleImporter = HandleImporter::getInstance();
@@ -103,6 +103,12 @@
                 __FUNCTION__, mCameraId.c_str());
         mInitFail = true;
     }
+
+    mAshmemAllocator = IAllocator::getService("ashmem");
+    if (mAshmemAllocator == nullptr) {
+        ALOGI("%s: cannot get ashmemAllocator", __FUNCTION__);
+        mInitFail = true;
+    }
 }
 
 CameraDevice::~CameraDevice() {
@@ -253,10 +259,7 @@
     }
 
     object->cleanUpCirculatingBuffers();
-    ProducerUsageFlags producerUsage;
-    uint64_t consumerUsage;
-    ::android_convertGralloc0To1Usage(usage, &producerUsage, &consumerUsage);
-    return getStatusT(object->mPreviewCallback->setUsage(producerUsage));
+    return getStatusT(object->mPreviewCallback->setUsage((ProducerUsage) usage));
 }
 
 int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
@@ -293,35 +296,66 @@
     return getStatusT(s);
 }
 
-CameraDevice::CameraHeapMemory::CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers) :
+CameraDevice::CameraHeapMemory::CameraHeapMemory(
+    int fd, size_t buf_size, uint_t num_buffers) :
         mBufSize(buf_size),
         mNumBufs(num_buffers) {
-    mHeap = new MemoryHeapBase(fd, buf_size * num_buffers);
+    mHidlHandle = native_handle_create(1,0);
+    mHidlHandle->data[0] = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+    const size_t pagesize = getpagesize();
+    size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
+    mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
     commonInitialization();
 }
 
-CameraDevice::CameraHeapMemory::CameraHeapMemory(size_t buf_size, uint_t num_buffers) :
+CameraDevice::CameraHeapMemory::CameraHeapMemory(
+    sp<IAllocator> ashmemAllocator,
+    size_t buf_size, uint_t num_buffers) :
         mBufSize(buf_size),
         mNumBufs(num_buffers) {
-    mHeap = new MemoryHeapBase(buf_size * num_buffers);
+    const size_t pagesize = getpagesize();
+    size_t size = ((buf_size * num_buffers + pagesize-1) & ~(pagesize-1));
+    ashmemAllocator->allocate(size,
+        [&](bool success, const hidl_memory& mem) {
+            if (!success) {
+                ALOGE("%s: allocating ashmem of %zu bytes failed!",
+                        __FUNCTION__, buf_size * num_buffers);
+                return;
+            }
+            mHidlHandle = native_handle_clone(mem.handle());
+            mHidlHeap = hidl_memory("ashmem", mHidlHandle, size);
+        });
+
     commonInitialization();
 }
 
 void CameraDevice::CameraHeapMemory::commonInitialization() {
-    handle.data = mHeap->base();
+    mHidlHeapMemory = mapMemory(mHidlHeap);
+    if (mHidlHeapMemory == nullptr) {
+        ALOGE("%s: memory map failed!", __FUNCTION__);
+        native_handle_close(mHidlHandle); // close FD for the shared memory
+        native_handle_delete(mHidlHandle);
+        mHidlHeap = hidl_memory();
+        mHidlHandle = nullptr;
+        return;
+    }
+    mHidlHeapMemData = mHidlHeapMemory->getPointer();
+    handle.data = mHidlHeapMemData;
     handle.size = mBufSize * mNumBufs;
     handle.handle = this;
-
-    mBuffers = new sp<MemoryBase>[mNumBufs];
-    for (uint_t i = 0; i < mNumBufs; i++) {
-        mBuffers[i] = new MemoryBase(mHeap, i * mBufSize, mBufSize);
-    }
-
     handle.release = sPutMemory;
 }
 
 CameraDevice::CameraHeapMemory::~CameraHeapMemory() {
-    delete [] mBuffers;
+    if (mHidlHeapMemory != nullptr) {
+        mHidlHeapMemData = nullptr;
+        mHidlHeapMemory.clear(); // The destructor will trigger munmap
+    }
+
+    if (mHidlHandle) {
+        native_handle_close(mHidlHandle); // close FD for the shared memory
+        native_handle_delete(mHidlHandle);
+    }
 }
 
 // shared memory methods
@@ -334,22 +368,13 @@
     }
 
     CameraHeapMemory* mem;
-    native_handle_t* handle = native_handle_create(1,0);
-
-    if (handle == nullptr) {
-        ALOGE("%s: native_handle_create failed!", __FUNCTION__);
-        return nullptr;
-    }
-
     if (fd < 0) {
-        mem = new CameraHeapMemory(buf_size, num_bufs);
+        mem = new CameraHeapMemory(object->mAshmemAllocator, buf_size, num_bufs);
     } else {
         mem = new CameraHeapMemory(fd, buf_size, num_bufs);
     }
-    handle->data[0] = mem->mHeap->getHeapID();
     mem->incStrong(mem);
-
-    hidl_handle hidlHandle = handle;
+    hidl_handle hidlHandle = mem->mHidlHandle;
     MemoryId id = object->mDeviceCallback->registerMemory(hidlHandle, buf_size, num_bufs);
     mem->handle.mId = id;
     if (object->mMemoryMap.count(id) != 0) {
@@ -357,7 +382,6 @@
     }
     object->mMemoryMap[id] = mem;
     mem->handle.mDevice = object;
-    native_handle_delete(handle);
     return &mem->handle;
 }
 
@@ -475,7 +499,7 @@
     if (object->mMetadataMode) {
         if (mem->mBufSize == sizeof(VideoNativeHandleMetadata)) {
             VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
-                    mem->mBuffers[index]->pointer();
+                    ((uint8_t*) mem->mHidlHeapMemData + index * mem->mBufSize);
             if (md->eType == VideoNativeHandleMetadata::kMetadataBufferTypeNativeHandleSource) {
                 handle = md->pHandle;
             }
@@ -805,27 +829,12 @@
     }
     if (mDevice->ops->release_recording_frame) {
         CameraHeapMemory* camMemory = mMemoryMap.at(memId);
-        sp<MemoryHeapBase> heap = camMemory->mHeap;
         if (bufferIndex >= camMemory->mNumBufs) {
             ALOGE("%s: bufferIndex %d exceeds number of buffers %d",
                     __FUNCTION__, bufferIndex, camMemory->mNumBufs);
             return;
         }
-        sp<IMemory> mem = camMemory->mBuffers[bufferIndex];
-        // TODO: simplify below logic once we verify offset is indeed idx * mBufSize
-        //       and heap == heap2
-        ssize_t offset;
-        size_t size;
-        sp<IMemoryHeap> heap2 = mem->getMemory(&offset, &size);
-        if ((size_t)offset != bufferIndex * camMemory->mBufSize) {
-            ALOGI("%s: unexpected offset %zd (was expecting %zu)",
-                    __FUNCTION__, offset, bufferIndex * camMemory->mBufSize);
-        }
-        if (heap != heap2) {
-            ALOGE("%s: heap mismatch!", __FUNCTION__);
-            return;
-        }
-        void *data = ((uint8_t *)heap->base()) + offset;
+        void *data = ((uint8_t *) camMemory->mHidlHeapMemData) + bufferIndex * camMemory->mBufSize;
         if (handle) {
             VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*) data;
             if (md->eType == VideoNativeHandleMetadata::kMetadataBufferTypeNativeHandleSource) {
diff --git a/camera/device/1.0/default/CameraDevice_1_0.h b/camera/device/1.0/default/CameraDevice_1_0.h
index ad5f582..a9f55c2 100644
--- a/camera/device/1.0/default/CameraDevice_1_0.h
+++ b/camera/device/1.0/default/CameraDevice_1_0.h
@@ -20,12 +20,12 @@
 #include <unordered_map>
 #include "utils/Mutex.h"
 #include "utils/SortedVector.h"
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
 #include "CameraModule.h"
 #include "HandleImporter.h"
 
 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 
@@ -47,7 +47,9 @@
 using ::android::hardware::camera::device::V1_0::ICameraDeviceCallback;
 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
 using ::android::hardware::camera::device::V1_0::MemoryId;
+using ::android::hidl::allocator::V1_0::IAllocator;
 using ::android::hidl::base::V1_0::IBase;
+using ::android::hidl::memory::V1_0::IMemory;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_memory;
 using ::android::hardware::hidl_string;
@@ -113,17 +115,24 @@
     class CameraHeapMemory : public RefBase {
     public:
         CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1);
-        explicit CameraHeapMemory(size_t buf_size, uint_t num_buffers = 1);
+        explicit CameraHeapMemory(
+            sp<IAllocator> ashmemAllocator, size_t buf_size, uint_t num_buffers = 1);
         void commonInitialization();
         virtual ~CameraHeapMemory();
 
         size_t mBufSize;
         uint_t mNumBufs;
-        // TODO: b/35887419: use hidl_memory instead and get rid of libbinder
-        sp<MemoryHeapBase> mHeap;
-        sp<MemoryBase>* mBuffers;
+
+        // Shared memory related members
+        hidl_memory      mHidlHeap;
+        native_handle_t* mHidlHandle; // contains one shared memory FD
+        void*            mHidlHeapMemData;
+        sp<IMemory>      mHidlHeapMemory; // munmap happens in ~IMemory()
+
         CameraMemory handle;
     };
+    sp<IAllocator> mAshmemAllocator;
+
 
     // TODO: b/35625849
     // Meta data buffer layout for passing a native_handle to codec
diff --git a/camera/device/1.0/types.hal b/camera/device/1.0/types.hal
index 0b3445f..ce5205e 100644
--- a/camera/device/1.0/types.hal
+++ b/camera/device/1.0/types.hal
@@ -16,10 +16,6 @@
 
 package android.hardware.camera.device@1.0;
 
-import android.hardware.graphics.allocator@2.0::types;
-
-typedef bitfield<ProducerUsage> ProducerUsageFlags;
-
 enum CameraFacing : uint32_t {
     /** The facing of the camera is opposite to that of the screen. */
     BACK = 0,
diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp
index 5a81d41..e0dc5ff 100644
--- a/camera/device/3.2/default/Android.bp
+++ b/camera/device/3.2/default/Android.bp
@@ -17,8 +17,7 @@
         "libcamera_metadata"
     ],
     static_libs: [
-        "android.hardware.camera.common@1.0-helper",
-        "libgrallocusage"
+        "android.hardware.camera.common@1.0-helper"
     ],
     export_include_dirs: ["."]
 }
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index f2f9e5e..5b3024b 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -611,7 +611,7 @@
                 return Void();
             }
             mStreamMap[id].rotation = (int) requestedConfiguration.streams[i].rotation;
-            mStreamMap[id].usage = convertFromHidlUsage(requestedConfiguration.streams[i].usage);
+            mStreamMap[id].usage = (uint32_t) requestedConfiguration.streams[i].usage;
         }
         streams[i] = &mStreamMap[id];
     }
diff --git a/camera/device/3.2/default/convert.cpp b/camera/device/3.2/default/convert.cpp
index c99d903..35676df 100644
--- a/camera/device/3.2/default/convert.cpp
+++ b/camera/device/3.2/default/convert.cpp
@@ -15,12 +15,8 @@
  */
 
 #define LOG_TAG "android.hardware.camera.device@3.2-convert-impl"
-#include <inttypes.h>
-
 #include <android/log.h>
 
-#include <grallocusage/GrallocUsageConversion.h>
-
 #include "include/convert.h"
 
 namespace android {
@@ -32,7 +28,6 @@
 
 using ::android::hardware::graphics::common::V1_0::Dataspace;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::graphics::allocator::V2_0::ConsumerUsage;
 using ::android::hardware::camera::device::V3_2::ConsumerUsageFlags;
 using ::android::hardware::camera::device::V3_2::ProducerUsageFlags;
 
@@ -71,37 +66,23 @@
     dst->format = (int) src.format;
     dst->data_space = (android_dataspace_t) src.dataSpace;
     dst->rotation = (int) src.rotation;
-    dst->usage = convertFromHidlUsage(src.usage);
+    dst->usage = (uint32_t) src.usage;
     // Fields to be filled by HAL (max_buffers, priv) are initialized to 0
     dst->max_buffers = 0;
     dst->priv = 0;
     return;
 }
 
-uint32_t convertFromHidlUsage(ConsumerUsageFlags usage) {
-    uint32_t dstUsage = 0;
-    dstUsage = ::android_convertGralloc1To0Usage(/*producerUsage*/ 0, usage);
-    // Compatibility workaround - add HW_CAMERA_ZSL when ConsumerUsage.CAMERA is set, to
-    // match pre-HIDL expected usage flags
-    if ( (usage & ConsumerUsage::CAMERA) == static_cast<uint64_t>(ConsumerUsage::CAMERA)) {
-        dstUsage |= GRALLOC_USAGE_HW_CAMERA_ZSL;
-    }
-    return dstUsage;
-}
-
 void convertToHidl(const Camera3Stream* src, HalStream* dst) {
     dst->id = src->mId;
     dst->overrideFormat = (PixelFormat) src->format;
     dst->maxBuffers = src->max_buffers;
-    ConsumerUsageFlags consumerUsage;
-    ProducerUsageFlags producerUsage;
-    ::android_convertGralloc0To1Usage(src->usage, &producerUsage, &consumerUsage);
     if (src->stream_type == CAMERA3_STREAM_OUTPUT) {
         dst->consumerUsage = (ConsumerUsageFlags) 0;
-        dst->producerUsage = producerUsage;
+        dst->producerUsage = (ProducerUsageFlags) src->usage;
     } else if (src->stream_type == CAMERA3_STREAM_INPUT) {
         dst->producerUsage = (ProducerUsageFlags) 0;
-        dst->consumerUsage = consumerUsage;
+        dst->consumerUsage = (ConsumerUsageFlags) src->usage;
     } else {
         //Should not reach here per current HIDL spec, but we might end up adding
         // bi-directional stream to HIDL.
diff --git a/camera/device/3.2/default/include/convert.h b/camera/device/3.2/default/include/convert.h
index 7c8e02f..96891f0 100644
--- a/camera/device/3.2/default/include/convert.h
+++ b/camera/device/3.2/default/include/convert.h
@@ -45,8 +45,6 @@
 void convertFromHidl(const Stream &src, Camera3Stream* dst);
 void convertToHidl(const Camera3Stream* src, HalStream* dst);
 
-uint32_t convertFromHidlUsage(ConsumerUsageFlags usage);
-
 void convertFromHidl(
         buffer_handle_t*, BufferStatus, camera3_stream_t*, int acquireFence, // inputs
         camera3_stream_buffer_t* dst);
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index 42dec4d..9506827 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -15,6 +15,8 @@
         "camera.device@3.2-impl",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.common@1.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
         "liblog",
         "libhardware",
         "libcamera_metadata"
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/CameraProvider.cpp
index 8701ec1..9f4d188 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/CameraProvider.cpp
@@ -40,6 +40,22 @@
 const int kMaxCameraDeviceNameLen = 128;
 const int kMaxCameraIdLen = 16;
 
+bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
+                     std::string* cameraId) {
+    std::string deviceNameStd(deviceName.c_str());
+    std::smatch sm;
+    if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
+        if (deviceVersion != nullptr) {
+            *deviceVersion = sm[1];
+        }
+        if (cameraId != nullptr) {
+            *cameraId = sm[2];
+        }
+        return true;
+    }
+    return false;
+}
+
 } // anonymous namespace
 
 using ::android::hardware::camera::common::V1_0::CameraMetadataType;
@@ -112,30 +128,22 @@
     }
 }
 
-bool CameraProvider::matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
-    std::string deviceNameStd(deviceName.c_str());
-    return std::regex_match(deviceNameStd, sm, kDeviceNameRE);
-}
-
 std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
-    std::smatch sm;
-    bool match = matchDeviceName(deviceName, sm);
-    if (!match) {
-        return std::string("");
-    }
-    return sm[2];
+    std::string cameraId;
+    matchDeviceName(deviceName, nullptr, &cameraId);
+    return cameraId;
 }
 
 int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
-    std::smatch sm;
-    bool match = matchDeviceName(deviceName, sm);
+    std::string deviceVersion;
+    bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
     if (!match) {
         return -1;
     }
-    if (sm[1].compare(kHAL3_2) == 0) {
+    if (deviceVersion == kHAL3_2) {
         // maybe switched to 3.4 or define the hidl version enum later
         return CAMERA_DEVICE_API_VERSION_3_2;
-    } else if (sm[1].compare(kHAL1_0) == 0) {
+    } else if (deviceVersion == kHAL1_0) {
         return CAMERA_DEVICE_API_VERSION_1_0;
     }
     return 0;
@@ -322,15 +330,13 @@
 
 Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
         const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
-    std::smatch sm;
-    bool match = matchDeviceName(cameraDeviceName, sm);
+    std::string cameraId, deviceVersion;
+    bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
     if (!match) {
         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
         return Void();
     }
 
-    std::string cameraId = sm[2];
-    std::string deviceVersion = sm[1];
     std::string deviceName(cameraDeviceName.c_str());
     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
@@ -377,15 +383,13 @@
 
 Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
         const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
-    std::smatch sm;
-    bool match = matchDeviceName(cameraDeviceName, sm);
+    std::string cameraId, deviceVersion;
+    bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
     if (!match) {
         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
         return Void();
     }
 
-    std::string cameraId = sm[2];
-    std::string deviceVersion = sm[1];
     std::string deviceName(cameraDeviceName.c_str());
     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
diff --git a/camera/provider/2.4/default/CameraProvider.h b/camera/provider/2.4/default/CameraProvider.h
index 2a43e2f..d7b0ea6 100644
--- a/camera/provider/2.4/default/CameraProvider.h
+++ b/camera/provider/2.4/default/CameraProvider.h
@@ -91,7 +91,6 @@
     bool setUpVendorTags();
 
     // extract legacy camera ID/device version from a HIDL device name
-    static bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm);
     static std::string getLegacyCameraId(const hidl_string& deviceName);
     static int getCameraDeviceVersion(const hidl_string& deviceName);
 
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 02c42c9..a0be5cb 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -33,10 +33,7 @@
         "libgui",
         "libui"
     ],
-    static_libs: [
-        "VtsHalHidlTargetTestBase",
-        "libgrallocusage"
-    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
     cflags: [
         "-O0",
         "-g",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 4d3c6eb..74e6efe 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -21,7 +21,6 @@
 #include "CameraParameters.h"
 #include <system/camera.h>
 #include <android/log.h>
-#include <grallocusage/GrallocUsageConversion.h>
 #include <ui/GraphicBuffer.h>
 #include <VtsHalHidlTargetTestBase.h>
 #include <gui/BufferQueue.h>
@@ -54,7 +53,6 @@
 using ::android::Surface;
 using ::android::CameraParameters;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::graphics::allocator::V2_0::ConsumerUsage;
 using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
@@ -62,8 +60,6 @@
 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
-using ::android::hardware::camera::device::V3_2::ProducerUsageFlags;
-using ::android::hardware::camera::device::V3_2::ConsumerUsageFlags;
 using ::android::hardware::camera::device::V3_2::ICameraDevice;
 using ::android::hardware::camera::device::V3_2::BufferCache;
 using ::android::hardware::camera::device::V3_2::CaptureRequest;
@@ -84,7 +80,6 @@
 using ::android::hardware::camera::device::V3_2::MsgType;
 using ::android::hardware::camera::device::V3_2::ErrorMsg;
 using ::android::hardware::camera::device::V3_2::ErrorCode;
-using ::android::hardware::camera::device::V1_0::ProducerUsageFlags;
 using ::android::hardware::camera::device::V1_0::CameraFacing;
 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
 using ::android::hardware::camera::device::V1_0::CommandType;
@@ -238,7 +233,7 @@
     Return<Status> setCrop(int32_t left, int32_t top,
             int32_t right, int32_t bottom) override;
 
-    Return<Status> setUsage(ProducerUsageFlags usage) override;
+    Return<Status> setUsage(ProducerUsage usage) override;
 
     Return<Status> setSwapInterval(int32_t interval) override;
 
@@ -413,11 +408,10 @@
     return mapToStatus(rc);
 }
 
-Return<Status> PreviewWindowCb::setUsage(ProducerUsageFlags usage) {
-    int dstUsage = ::android_convertGralloc1To0Usage(usage, /*consumerUsage*/ 0);
-    auto rc = native_window_set_usage(mAnw.get(), dstUsage);
+Return<Status> PreviewWindowCb::setUsage(ProducerUsage usage) {
+    auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
     if (rc == ::android::OK) {
-        mPreviewUsage = dstUsage;
+        mPreviewUsage =  static_cast<int>(usage);
     }
     return mapToStatus(rc);
 }
@@ -2205,7 +2199,7 @@
                             static_cast<uint32_t> (input.width),
                             static_cast<uint32_t> (input.height),
                             static_cast<PixelFormat> (input.format),
-                            static_cast<ConsumerUsageFlags>(ConsumerUsage::CAMERA), 0,
+                            GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
                             StreamRotation::ROTATION_0};
                     Stream inputStream = {streamId++, StreamType::INPUT,
                             static_cast<uint32_t> (input.width),
@@ -2437,7 +2431,7 @@
                             static_cast<uint32_t> (blobIter.width),
                             static_cast<uint32_t> (blobIter.height),
                             static_cast<PixelFormat> (blobIter.format),
-                            static_cast<ConsumerUsageFlags>(ConsumerUsage::VIDEO_ENCODER), 0,
+                            GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
                             StreamRotation::ROTATION_0};
                     ::android::hardware::hidl_vec<Stream> streams = {
                             videoStream, blobStream};
diff --git a/configstore/1.0/default/SurfaceFlingerConfigs.cpp b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
index 9469ab4..70bd803 100644
--- a/configstore/1.0/default/SurfaceFlingerConfigs.cpp
+++ b/configstore/1.0/default/SurfaceFlingerConfigs.cpp
@@ -12,7 +12,6 @@
 Return<void> SurfaceFlingerConfigs::vsyncEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
 #ifdef VSYNC_EVENT_PHASE_OFFSET_NS
     _hidl_cb({true, VSYNC_EVENT_PHASE_OFFSET_NS});
-    LOG(INFO) << "vsync event phase offset ns =  " << VSYNC_EVENT_PHASE_OFFSET_NS;
 #else
     _hidl_cb({false, 0});
 #endif
@@ -22,7 +21,6 @@
 Return<void> SurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs(vsyncEventPhaseOffsetNs_cb _hidl_cb) {
 #ifdef SF_VSYNC_EVENT_PHASE_OFFSET_NS
     _hidl_cb({true, SF_VSYNC_EVENT_PHASE_OFFSET_NS});
-    LOG(INFO) << "sfvsync event phase offset ns =  " << SF_VSYNC_EVENT_PHASE_OFFSET_NS;
 #else
     _hidl_cb({false, 0});
 #endif
@@ -32,7 +30,6 @@
 Return<void> SurfaceFlingerConfigs::useContextPriority(useContextPriority_cb _hidl_cb) {
 #ifdef USE_CONTEXT_PRIORITY
     _hidl_cb({true, USE_CONTEXT_PRIORITY});
-    LOG(INFO) << "SurfaceFlinger useContextPriority=" << USE_CONTEXT_PRIORITY;
 #else
     _hidl_cb({false, false});
 #endif
@@ -42,7 +39,6 @@
 Return<void> SurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers(maxFrameBufferAcquiredBuffers_cb _hidl_cb) {
 #ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS
     _hidl_cb({true, NUM_FRAMEBUFFER_SURFACE_BUFFERS});
-    LOG(INFO) << "SurfaceFlinger FrameBuffer max acquired buffers : " << NUM_FRAMEBUFFER_SURFACE_BUFFERS;
 #else
     _hidl_cb({false, 0});
 #endif
@@ -55,7 +51,6 @@
     value = true;
 #endif
     _hidl_cb({true, value});
-    LOG(INFO) << "SurfaceFlinger Display: " << (value ? "Wide Color" : "Standard Color");
     return Void();
 }
 
@@ -65,7 +60,6 @@
     value = false;
 #endif
     _hidl_cb({true, value});
-    LOG(INFO) << "SurfaceFlinger hasSyncFramework: " << value;
     return Void();
 }
 
@@ -75,14 +69,12 @@
     value = true;
 #endif
     _hidl_cb({true, value});
-    LOG(INFO) << "SurfaceFlinger Display: " << (value ? "HDR" : "SDR");
     return Void();
 }
 
 Return<void> SurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs(presentTimeOffsetFromVSyncNs_cb _hidl_cb) {
 #ifdef PRESENT_TIME_OFFSET_FROM_VSYNC_NS
       _hidl_cb({true, PRESENT_TIME_OFFSET_FROM_VSYNC_NS});
-      LOG(INFO) << "SurfaceFlinger presentTimeStampOffsetNs =  " << PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
 #else
       _hidl_cb({false, 0});
 #endif
@@ -95,7 +87,6 @@
     value = true;
 #endif
     _hidl_cb({true, value});
-    LOG(INFO) << "SurfaceFlinger forceHwcForRGBtoYUV: " << value;
     return Void();
 }
 
@@ -104,7 +95,6 @@
 #ifdef MAX_VIRTUAL_DISPLAY_DIMENSION
   maxSize = MAX_VIRTUAL_DISPLAY_DIMENSION;
   _hidl_cb({true, maxSize});
-  LOG(INFO) << "SurfaceFlinger MaxVirtualDisplaySize: " << maxSize;
 #else
   _hidl_cb({false, maxSize});
 #endif
@@ -119,7 +109,6 @@
     specified = true;
 #endif
     _hidl_cb({specified, value});
-    LOG(INFO) << "SurfaceFlinger UseVrFlinger: " << (value ? "true" : "false");
     return Void();
 }
 
diff --git a/configstore/utils/Android.bp b/configstore/utils/Android.bp
index aa420d1..2c8aad6 100644
--- a/configstore/utils/Android.bp
+++ b/configstore/utils/Android.bp
@@ -14,14 +14,22 @@
 // limitations under the License.
 //
 
-cc_library_headers {
+cc_library_shared {
     name: "android.hardware.configstore-utils",
     defaults: ["hidl_defaults"],
+
+    srcs: [ "ConfigStoreUtils.cpp" ],
+
     export_include_dirs: ["include"],
+
     shared_libs: [
+        "android.hardware.configstore@1.0",
+        "libbase",
         "libhidlbase"
     ],
     export_shared_lib_headers: [
+        "android.hardware.configstore@1.0",
+        "libbase",
         "libhidlbase"
     ],
 }
diff --git a/configstore/utils/ConfigStoreUtils.cpp b/configstore/utils/ConfigStoreUtils.cpp
new file mode 100644
index 0000000..5a1fb42
--- /dev/null
+++ b/configstore/utils/ConfigStoreUtils.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#define LOG_TAG "ConfigStore"
+
+#include <android-base/logging.h>
+#include <configstore/Utils.h>
+
+namespace android {
+namespace hardware {
+namespace details {
+
+bool wouldLogInfo() {
+    return WOULD_LOG(INFO);
+}
+
+void logAlwaysInfo(const std::string& message) {
+    LOG(INFO) << message;
+}
+
+void logAlwaysError(const std::string& message) {
+    LOG(ERROR) << message;
+}
+
+}  // namespace details
+}  // namespace hardware
+}  // namespace android
diff --git a/configstore/utils/include/configstore/Utils.h b/configstore/utils/include/configstore/Utils.h
index 46cc9b0..a54ce85 100644
--- a/configstore/utils/include/configstore/Utils.h
+++ b/configstore/utils/include/configstore/Utils.h
@@ -17,24 +17,31 @@
 #ifndef ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
 #define ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
 
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <hidl/Status.h>
-#include <stdatomic.h>
 
-#pragma push_macro("LOG_TAG")
-#undef LOG_TAG
-#define LOG_TAG "ConfigStoreUtil"
+#include <sstream>
 
 namespace android {
 namespace hardware {
+
+namespace details {
+// Templated classes can use the below method
+// to avoid creating dependencies on liblog.
+bool wouldLogInfo();
+void logAlwaysInfo(const std::string& message);
+void logAlwaysError(const std::string& message);
+}  // namespace details
+
 namespace configstore {
+using namespace android::hardware::configstore::V1_0;
 // arguments V: type for the value (i.e., OptionalXXX)
 //           I: interface class name
 //           func: member function pointer
-using namespace V1_0;
-
 template<typename V, typename I, android::hardware::Return<void> (I::* func)
         (std::function<void(const V&)>)>
 decltype(V::value) get(const decltype(V::value) &defValue) {
+    using namespace android::hardware::details;
     auto getHelper = []()->V {
         V ret;
         sp<I> configs = I::getService();
@@ -47,7 +54,11 @@
                 ret = v;
             });
             if (!status.isOk()) {
-                ALOGE("HIDL call failed. %s", status.description().c_str());
+                std::ostringstream oss;
+                oss << "HIDL call failed for retrieving a config item from "
+                       "configstore : "
+                    << status.description().c_str();
+                logAlwaysError(oss.str());
                 ret.specified = false;
             }
         }
@@ -56,6 +67,24 @@
     };
     static V cachedValue = getHelper();
 
+    if (wouldLogInfo()) {
+        std::string iname = __PRETTY_FUNCTION__;
+        // func name starts with "func = " in __PRETTY_FUNCTION__
+        auto pos = iname.find("func = ");
+        if (pos != std::string::npos) {
+            iname = iname.substr(pos + sizeof("func = "));
+            iname.pop_back();  // remove trailing ']'
+        } else {
+            iname += " (unknown)";
+        }
+
+        std::ostringstream oss;
+        oss << iname << " retrieved: "
+            << (cachedValue.specified ? cachedValue.value : defValue)
+            << (cachedValue.specified ? "" : " (default)");
+        logAlwaysInfo(oss.str());
+    }
+
     return cachedValue.specified ? cachedValue.value : defValue;
 }
 
@@ -99,6 +128,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#pragma pop_macro("LOG_TAG")
-
 #endif  // ANDROID_HARDWARE_CONFIGSTORE_UTILS_H
diff --git a/drm/1.0/IDrmPlugin.hal b/drm/1.0/IDrmPlugin.hal
index 083b311..07b0832 100644
--- a/drm/1.0/IDrmPlugin.hal
+++ b/drm/1.0/IDrmPlugin.hal
@@ -179,10 +179,9 @@
      * certificate authority (CA) is an entity which issues digital certificates
      * for use by other parties. It is an example of a trusted third party.
      * @return status the status of the call. The status must be OK or one of
-     * the following errors: BAD_VALUE if the sessionId is invalid,
-     * ERROR_DRM_CANNOT_HANDLE if the drm scheme does not require provisioning
-     * or ERROR_DRM_INVALID_STATE if the HAL is in a state where the provision
-     * request cannot be generated.
+     * the following errors: ERROR_DRM_CANNOT_HANDLE if the drm scheme does not
+     * require provisioning or ERROR_DRM_INVALID_STATE if the HAL is in a state
+     * where the provision request cannot be generated.
      * @return request if successful the opaque certificate request blob
      * is returned
      * @return defaultUrl URL that the provisioning request should be
diff --git a/drm/1.0/default/Android.mk b/drm/1.0/default/Android.mk
index f2334a0..23a4506 100644
--- a/drm/1.0/default/Android.mk
+++ b/drm/1.0/default/Android.mk
@@ -38,9 +38,12 @@
 LOCAL_C_INCLUDES := \
   hardware/interfaces/drm
 
-# TODO: The legacy DRM plugins only support 32-bit. They need
-# to be migrated to 64-bit (b/18948909)
+# TODO(b/18948909) Some legacy DRM plugins only support 32-bit. They need to be
+# migrated to 64-bit. Once all of a device's legacy DRM plugins support 64-bit,
+# that device can turn on ENABLE_MEDIADRM_64 to build this service as 64-bit.
+ifneq ($(ENABLE_MEDIADRM_64), true)
 LOCAL_32_BIT_ONLY := true
+endif
 
 include $(BUILD_EXECUTABLE)
 
@@ -55,11 +58,13 @@
     DrmPlugin.cpp \
     CryptoFactory.cpp \
     CryptoPlugin.cpp \
+    LegacyPluginPath.cpp \
     TypeConvert.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.drm@1.0 \
     android.hidl.memory@1.0 \
+    libcutils \
     libhidlbase \
     libhidlmemory \
     libhidltransport \
@@ -72,8 +77,11 @@
     frameworks/native/include \
     frameworks/av/include
 
-# TODO: The legacy DRM plugins only support 32-bit. They need
-# to be migrated to 64-bit (b/18948909)
+# TODO: Some legacy DRM plugins only support 32-bit. They need to be migrated to
+# 64-bit. (b/18948909) Once all of a device's legacy DRM plugins support 64-bit,
+# that device can turn on ENABLE_MEDIADRM_64 to build this impl as 64-bit.
+ifneq ($(ENABLE_MEDIADRM_64), true)
 LOCAL_32_BIT_ONLY := true
+endif
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/1.0/default/CryptoFactory.cpp b/drm/1.0/default/CryptoFactory.cpp
index e46233d..935786d 100644
--- a/drm/1.0/default/CryptoFactory.cpp
+++ b/drm/1.0/default/CryptoFactory.cpp
@@ -17,6 +17,7 @@
 
 #include "CryptoFactory.h"
 #include "CryptoPlugin.h"
+#include "LegacyPluginPath.h"
 #include "TypeConvert.h"
 #include <utils/Log.h>
 
@@ -27,7 +28,7 @@
 namespace implementation {
 
     CryptoFactory::CryptoFactory() :
-        loader("/vendor/lib/mediadrm", "createCryptoFactory") {
+        loader(getDrmPluginPath(), "createCryptoFactory") {
     }
 
     // Methods from ::android::hardware::drm::V1_0::ICryptoFactory follow.
diff --git a/drm/1.0/default/DrmFactory.cpp b/drm/1.0/default/DrmFactory.cpp
index 9ec0ab7..72466a1 100644
--- a/drm/1.0/default/DrmFactory.cpp
+++ b/drm/1.0/default/DrmFactory.cpp
@@ -1,6 +1,6 @@
 /*
  * 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
@@ -17,6 +17,7 @@
 
 #include "DrmFactory.h"
 #include "DrmPlugin.h"
+#include "LegacyPluginPath.h"
 #include "TypeConvert.h"
 #include <utils/Log.h>
 
@@ -27,7 +28,7 @@
 namespace implementation {
 
     DrmFactory::DrmFactory() :
-        loader("/vendor/lib/mediadrm", "createDrmFactory") {
+        loader(getDrmPluginPath(), "createDrmFactory") {
     }
 
     // Methods from ::android::hardware::drm::V1_0::IDrmFactory follow.
diff --git a/drm/1.0/default/LegacyPluginPath.cpp b/drm/1.0/default/LegacyPluginPath.cpp
new file mode 100644
index 0000000..369059d
--- /dev/null
+++ b/drm/1.0/default/LegacyPluginPath.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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 "LegacyPluginPath.h"
+
+#include <cutils/properties.h>
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+const char* getDrmPluginPath() {
+    if (property_get_bool("drm.64bit.enabled", false)) {
+        return "/vendor/lib64/mediadrm";
+    } else {
+        return "/vendor/lib/mediadrm";
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
diff --git a/drm/1.0/default/LegacyPluginPath.h b/drm/1.0/default/LegacyPluginPath.h
new file mode 100644
index 0000000..7145f2e
--- /dev/null
+++ b/drm/1.0/default/LegacyPluginPath.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 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 LEGACY_PLUGIN_PATH_H_
+
+#define LEGACY_PLUGIN_PATH_H_
+
+namespace android {
+namespace hardware {
+namespace drm {
+namespace V1_0 {
+namespace implementation {
+
+const char* getDrmPluginPath();
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace drm
+}  // namespace hardware
+}  // namespace android
+
+#endif  // LEGACY_PLUGIN_PATH_H_
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
index dcfee4e..bd78442c 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -973,8 +973,12 @@
         testing::ValuesIn(gVendorModules->getVendorModulePaths()));
 
 int main(int argc, char** argv) {
-    gVendorModules =
-            new drm_vts::VendorModules("/data/nativetest/drm_hidl_test/vendor");
+#if defined(__LP64__)
+    const char *kModulePath = "/data/local/tmp/64/lib";
+#else
+    const char *kModulePath = "/data/local/tmp/32/lib";
+#endif
+    gVendorModules = new drm_vts::VendorModules(kModulePath);
     ::testing::InitGoogleTest(&argc, argv);
     return RUN_ALL_TESTS();
 }
diff --git a/drm/1.0/vts/functional/vendor/lib/libvtswidevine.so b/drm/1.0/vts/functional/vendor/lib/libvtswidevine.so
deleted file mode 100755
index d365b34..0000000
--- a/drm/1.0/vts/functional/vendor/lib/libvtswidevine.so
+++ /dev/null
Binary files differ
diff --git a/gnss/1.0/IGnssDebug.hal b/gnss/1.0/IGnssDebug.hal
index 716ba88..4c4cfb8 100644
--- a/gnss/1.0/IGnssDebug.hal
+++ b/gnss/1.0/IGnssDebug.hal
@@ -71,8 +71,8 @@
         /** Represents heading in degrees. */
         float bearingDegrees;
         /**
-         * Estimated horizontal accuracy of position expressed in meters, radial,
-         * 68% confidence.
+         * Estimated horizontal accuracy of position expressed in meters,
+         * radial, 68% confidence.
          */
         double horizontalAccuracyMeters;
         /**
@@ -126,7 +126,11 @@
         /** Defines the constellation type of the given SV. */
         GnssConstellationType constellation;
 
-        /** Defines the ephemeris type of the satellite. */
+        /**
+         * Defines the standard broadcast ephemeris or almanac availability for
+         * the satellite.  To report status of predicted orbit and clock
+         * information, see the serverPrediction fields below.
+         */
         SatelliteEphemerisType ephemerisType;
         /** Defines the ephemeris source of the satellite. */
         SatelliteEphemerisSource ephemerisSource;
@@ -143,7 +147,7 @@
         float ephemerisAgeSeconds;
 
         /**
-         * True if a server has provided a predicted orbit (& clock) for
+         * True if a server has provided a predicted orbit and clock model for
          * this satellite.
          */
         bool serverPredictionIsAvailable;
diff --git a/keymaster/3.0/vts/functional/Android.mk b/keymaster/3.0/vts/functional/Android.mk
index 4265b9f..4098664 100644
--- a/keymaster/3.0/vts/functional/Android.mk
+++ b/keymaster/3.0/vts/functional/Android.mk
@@ -15,7 +15,7 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := keymaster_hidl_hal_test
+LOCAL_MODULE := VtsHalKeymasterV3_0TargetTest
 LOCAL_SRC_FILES := \
         authorization_set.cpp \
         attestation_record.cpp \
diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
index 2382f0b..edb1cd1 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -46,6 +46,8 @@
 // non-gtest argument will be used as the service name.
 string service_name = "default";
 
+static bool arm_deleteAllKeys = false;
+
 namespace android {
 namespace hardware {
 
@@ -488,13 +490,20 @@
         return ExportKey(format, key_blob_, client_id, app_data, key_material);
     }
 
-    ErrorCode DeleteKey(HidlBuf* key_blob) {
+    ErrorCode DeleteKey(HidlBuf* key_blob, bool keep_key_blob = false) {
         ErrorCode error = keymaster_->deleteKey(*key_blob);
-        *key_blob = HidlBuf();
+        if (!keep_key_blob) *key_blob = HidlBuf();
         return error;
     }
 
-    ErrorCode DeleteKey() { return DeleteKey(&key_blob_); }
+    ErrorCode DeleteKey(bool keep_key_blob = false) {
+        return DeleteKey(&key_blob_, keep_key_blob);
+    }
+
+    ErrorCode DeleteAllKeys() {
+        ErrorCode error = keymaster_->deleteAllKeys();
+        return error;
+    }
 
     ErrorCode GetCharacteristics(const HidlBuf& key_blob, const HidlBuf& client_id,
                                  const HidlBuf& app_data, KeyCharacteristics* key_characteristics) {
@@ -3893,6 +3902,124 @@
                         &cert_chain));
 }
 
+typedef KeymasterHidlTest KeyDeletionTest;
+
+/**
+ * KeyDeletionTest.DeleteKey
+ *
+ * This test checks that if rollback protection is implemented, DeleteKey invalidates a formerly
+ * valid key blob.
+ */
+TEST_F(KeyDeletionTest, DeleteKey) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                             .RsaSigningKey(1024, 3)
+                                             .Digest(Digest::NONE)
+                                             .Padding(PaddingMode::NONE)
+                                             .Authorization(TAG_NO_AUTH_REQUIRED)));
+
+    // Delete must work if rollback protection is implemented
+    AuthorizationSet teeEnforced(key_characteristics_.teeEnforced);
+    bool rollback_protected = teeEnforced.Contains(TAG_ROLLBACK_RESISTANT);
+
+    if (rollback_protected) {
+        ASSERT_EQ(ErrorCode::OK, DeleteKey(true /* keep key blob */));
+    } else {
+        auto delete_result = DeleteKey(true /* keep key blob */);
+        ASSERT_TRUE(delete_result == ErrorCode::OK | delete_result == ErrorCode::UNIMPLEMENTED);
+    }
+
+    string message = "12345678901234567890123456789012";
+    AuthorizationSet begin_out_params;
+
+    if (rollback_protected) {
+        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+                Begin(KeyPurpose::SIGN, key_blob_,
+                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
+                        &begin_out_params, &op_handle_));
+    } else {
+        EXPECT_EQ(ErrorCode::OK,
+                Begin(KeyPurpose::SIGN, key_blob_,
+                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
+                        &begin_out_params, &op_handle_));
+    }
+    AbortIfNeeded();
+    key_blob_ = HidlBuf();
+}
+
+/**
+ * KeyDeletionTest.DeleteInvalidKey
+ *
+ * This test checks that the HAL excepts invalid key blobs.
+ */
+TEST_F(KeyDeletionTest, DeleteInvalidKey) {
+    // Generate key just to check if rollback protection is implemented
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                             .RsaSigningKey(1024, 3)
+                                             .Digest(Digest::NONE)
+                                             .Padding(PaddingMode::NONE)
+                                             .Authorization(TAG_NO_AUTH_REQUIRED)));
+
+    // Delete must work if rollback protection is implemented
+    AuthorizationSet teeEnforced(key_characteristics_.teeEnforced);
+    bool rollback_protected = teeEnforced.Contains(TAG_ROLLBACK_RESISTANT);
+
+    // Delete the key we don't care about the result at this point.
+    DeleteKey();
+
+    // Now create an invalid key blob and delete it.
+    key_blob_ = HidlBuf("just some garbage data which is not a valid key blob");
+
+    if (rollback_protected) {
+        ASSERT_EQ(ErrorCode::OK, DeleteKey());
+    } else {
+        auto delete_result = DeleteKey();
+        ASSERT_TRUE(delete_result == ErrorCode::OK | delete_result == ErrorCode::UNIMPLEMENTED);
+    }
+}
+
+/**
+ * KeyDeletionTest.DeleteAllKeys
+ *
+ * This test is disarmed by default. To arm it use --arm_deleteAllKeys.
+ *
+ * BEWARE: This test has serious side effects. All user keys will be lost! This includes
+ * FBE/FDE encryption keys, which means that the device will not even boot until after the
+ * device has been wiped manually (e.g., fastboot flashall -w), and new FBE/FDE keys have
+ * been provisioned. Use this test only on dedicated testing devices that have no valuable
+ * credentials stored in Keystore/Keymaster.
+ */
+TEST_F(KeyDeletionTest, DeleteAllKeys) {
+    if (!arm_deleteAllKeys) return;
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                             .RsaSigningKey(1024, 3)
+                                             .Digest(Digest::NONE)
+                                             .Padding(PaddingMode::NONE)
+                                             .Authorization(TAG_NO_AUTH_REQUIRED)));
+
+    // Delete must work if rollback protection is implemented
+    AuthorizationSet teeEnforced(key_characteristics_.teeEnforced);
+    bool rollback_protected = teeEnforced.Contains(TAG_ROLLBACK_RESISTANT);
+
+    ASSERT_EQ(ErrorCode::OK, DeleteAllKeys());
+
+    string message = "12345678901234567890123456789012";
+    AuthorizationSet begin_out_params;
+
+    if (rollback_protected) {
+        EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+                Begin(KeyPurpose::SIGN, key_blob_,
+                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
+                        &begin_out_params, &op_handle_));
+    } else {
+        EXPECT_EQ(ErrorCode::OK,
+                Begin(KeyPurpose::SIGN, key_blob_,
+                        AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
+                        &begin_out_params, &op_handle_));
+    }
+    AbortIfNeeded();
+    key_blob_ = HidlBuf();
+}
+
 }  // namespace test
 }  // namespace V3_0
 }  // namespace keymaster
@@ -3901,9 +4028,19 @@
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
-    if (argc == 2) {
-        ALOGI("Running keymaster VTS against service \"%s\"", argv[1]);
-        service_name = argv[1];
+    std::vector<std::string> positional_args;
+    for (int i = 1; i < argc; ++i) {
+        if (argv[i][0] == '-') {
+            if (std::string(argv[i]) == "--arm_deleteAllKeys") {
+                arm_deleteAllKeys = true;
+            }
+        } else {
+            positional_args.push_back(argv[i]);
+        }
+    }
+    if (positional_args.size()) {
+        ALOGI("Running keymaster VTS against service \"%s\"", positional_args[0].c_str());
+        service_name = positional_args[0];
     }
     int status = RUN_ALL_TESTS();
     ALOGI("Test result = %d", status);
diff --git a/usb/1.0/default/service.cpp b/usb/1.0/default/service.cpp
index 4605a4c..43ab6f0 100644
--- a/usb/1.0/default/service.cpp
+++ b/usb/1.0/default/service.cpp
@@ -27,13 +27,21 @@
 using android::hardware::usb::V1_0::IUsb;
 using android::hardware::usb::V1_0::implementation::Usb;
 
+using android::status_t;
+using android::OK;
+
 int main() {
 
     android::sp<IUsb> service = new Usb();
 
     configureRpcThreadpool(1, true /*callerWillJoin*/);
-    service->registerAsService();
+    status_t status = service->registerAsService();
 
-    ALOGI("USB HAL Ready.");
-    joinRpcThreadpool();
+    if (status == OK) {
+        ALOGI("USB HAL Ready.");
+        joinRpcThreadpool();
+    }
+
+    ALOGE("Cannot register USB HAL service");
+    return 1;
 }
diff --git a/wifi/1.0/default/hidl_callback_util.h b/wifi/1.0/default/hidl_callback_util.h
index 7136279..b7100c8 100644
--- a/wifi/1.0/default/hidl_callback_util.h
+++ b/wifi/1.0/default/hidl_callback_util.h
@@ -82,7 +82,7 @@
     return true;
   }
 
-  const std::set<android::sp<CallbackType>> getCallbacks() { return cb_set_; }
+  const std::set<android::sp<CallbackType>>& getCallbacks() { return cb_set_; }
 
   // Death notification for callbacks.
   void onObjectDeath(uint64_t cookie) {
diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp
index c005213..83b2e53 100644
--- a/wifi/1.0/default/hidl_struct_util.cpp
+++ b/wifi/1.0/default/hidl_struct_util.cpp
@@ -417,17 +417,25 @@
     const wifi_ie& legacy_ie = (*reinterpret_cast<const wifi_ie*>(next_ie));
     uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
     if (next_ie + curr_ie_len > ies_end) {
-      return false;
+      LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void *)next_ie
+                 << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void *)ies_end;
+      break;
     }
     WifiInformationElement hidl_ie;
     if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) {
-      return false;
+      LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id
+                 << ", len: " << legacy_ie.len;
+      break;
     }
     hidl_ies->push_back(std::move(hidl_ie));
     next_ie += curr_ie_len;
   }
-  // Ensure that the blob has been fully consumed.
-  return (next_ie == ies_end);
+  // Check if the blob has been fully consumed.
+  if (next_ie != ies_end) {
+    LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void *)next_ie
+               << ", IEs End: " << (void *)ies_end;
+  }
+  return true;
 }
 
 bool convertLegacyGscanResultToHidl(
@@ -774,10 +782,104 @@
   CHECK(false);
 }
 
+legacy_hal::NanMatchAlg convertHidlNanMatchAlgToLegacy(NanMatchAlg type) {
+  switch (type) {
+    case NanMatchAlg::MATCH_ONCE:
+      return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE;
+    case NanMatchAlg::MATCH_CONTINUOUS:
+      return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+    case NanMatchAlg::MATCH_NEVER:
+      return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER;
+  }
+  CHECK(false);
+}
+
+legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(NanPublishType type) {
+  switch (type) {
+    case NanPublishType::UNSOLICITED:
+      return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
+    case NanPublishType::SOLICITED:
+      return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED;
+    case NanPublishType::UNSOLICITED_SOLICITED:
+      return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+  }
+  CHECK(false);
+}
+
+legacy_hal::NanTxType convertHidlNanTxTypeToLegacy(NanTxType type) {
+  switch (type) {
+    case NanTxType::BROADCAST:
+      return legacy_hal::NAN_TX_TYPE_BROADCAST;
+    case NanTxType::UNICAST:
+      return legacy_hal::NAN_TX_TYPE_UNICAST;
+  }
+  CHECK(false);
+}
+
+legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(NanSubscribeType type) {
+  switch (type) {
+    case NanSubscribeType::PASSIVE:
+      return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
+    case NanSubscribeType::ACTIVE:
+      return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE;
+  }
+  CHECK(false);
+}
+
+legacy_hal::NanSRFType convertHidlNanSrfTypeToLegacy(NanSrfType type) {
+  switch (type) {
+    case NanSrfType::BLOOM_FILTER:
+      return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER;
+    case NanSrfType::PARTIAL_MAC_ADDR:
+      return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+  }
+  CHECK(false);
+}
+
+legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy(
+    NanDataPathChannelCfg type) {
+  switch (type) {
+    case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED:
+      return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED;
+    case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP:
+      return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP;
+    case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP:
+      return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP;
+  }
+  CHECK(false);
+}
+
 NanStatusType convertLegacyNanStatusTypeToHidl(
     legacy_hal::NanStatusType type) {
-  // values are identical - may need to do a mapping if they diverge in the future
-  return (NanStatusType) type;
+  switch (type) {
+    case legacy_hal::NAN_STATUS_SUCCESS:
+      return NanStatusType::SUCCESS;
+    case legacy_hal::NAN_STATUS_INTERNAL_FAILURE:
+      return NanStatusType::INTERNAL_FAILURE;
+    case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE:
+      return NanStatusType::PROTOCOL_FAILURE;
+    case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID:
+      return NanStatusType::INVALID_SESSION_ID;
+    case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE:
+      return NanStatusType::NO_RESOURCES_AVAILABLE;
+    case legacy_hal::NAN_STATUS_INVALID_PARAM:
+      return NanStatusType::INVALID_ARGS;
+    case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID:
+      return NanStatusType::INVALID_PEER_ID;
+    case legacy_hal::NAN_STATUS_INVALID_NDP_ID:
+      return NanStatusType::INVALID_NDP_ID;
+    case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED:
+      return NanStatusType::NAN_NOT_ALLOWED;
+    case legacy_hal::NAN_STATUS_NO_OTA_ACK:
+      return NanStatusType::NO_OTA_ACK;
+    case legacy_hal::NAN_STATUS_ALREADY_ENABLED:
+      return NanStatusType::ALREADY_ENABLED;
+    case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL:
+      return NanStatusType::FOLLOWUP_TX_QUEUE_FULL;
+    case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+      return NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+  }
+  CHECK(false);
 }
 
 bool convertHidlNanEnableRequestToLegacy(
@@ -931,7 +1033,7 @@
   memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
         legacy_request->service_name_len);
   legacy_request->publish_match_indicator =
-        (legacy_hal::NanMatchAlg) hidl_request.baseConfigs.discoveryMatchIndicator;
+        convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
   legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
   if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
     LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_specific_info_len too large";
@@ -1018,8 +1120,8 @@
   legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired ?
         legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
   legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
-  legacy_request->publish_type = (legacy_hal::NanPublishType) hidl_request.publishType;
-  legacy_request->tx_type = (legacy_hal::NanTxType) hidl_request.txType;
+  legacy_request->publish_type = convertHidlNanPublishTypeToLegacy(hidl_request.publishType);
+  legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType);
   legacy_request->service_responder_policy = hidl_request.autoAcceptDataPathRequests ?
         legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
 
@@ -1047,7 +1149,7 @@
   memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
         legacy_request->service_name_len);
   legacy_request->subscribe_match_indicator =
-        (legacy_hal::NanMatchAlg) hidl_request.baseConfigs.discoveryMatchIndicator;
+        convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
   legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
   if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
     LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: service_specific_info_len too large";
@@ -1134,8 +1236,8 @@
   legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired ?
         legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
   legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
-  legacy_request->subscribe_type = (legacy_hal::NanSubscribeType) hidl_request.subscribeType;
-  legacy_request->serviceResponseFilter = (legacy_hal::NanSRFType) hidl_request.srfType;
+  legacy_request->subscribe_type = convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType);
+  legacy_request->serviceResponseFilter = convertHidlNanSrfTypeToLegacy(hidl_request.srfType);
   legacy_request->serviceResponseInclude = hidl_request.srfRespondIfInAddressSet ?
         legacy_hal::NAN_SRF_INCLUDE_RESPOND : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
   legacy_request->useServiceResponseFilter = hidl_request.shouldUseSrf ?
@@ -1295,7 +1397,7 @@
   legacy_request->requestor_instance_id = hidl_request.peerId;
   memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6);
   legacy_request->channel_request_type =
-        (legacy_hal::NanDataPathChannelCfg) hidl_request.channelRequestType;
+        convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType);
   legacy_request->channel = hidl_request.channel;
   strcpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str());
   legacy_request->ndp_cfg.security_cfg = (hidl_request.securityConfig.securityType
diff --git a/wifi/1.0/default/wifi_chip.cpp b/wifi/1.0/default/wifi_chip.cpp
index 9c41a40..319e126 100644
--- a/wifi/1.0/default/wifi_chip.cpp
+++ b/wifi/1.0/default/wifi_chip.cpp
@@ -855,7 +855,8 @@
     for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
       if (!callback->onDebugRingBufferDataAvailable(hidl_status, data).isOk()) {
         LOG(ERROR) << "Failed to invoke onDebugRingBufferDataAvailable"
-                   << " callback";
+                   << " callback on: " << toString(callback);
+
       }
     }
   };