Merge "Detach thread so stop_measurement doesn't block" into sc-dev
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 21c1a6e..ffa0c13 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -134,6 +134,7 @@
     srcs: [
         "common/src/Obd2SensorStore.cpp",
         "common/src/VehicleObjectPool.cpp",
+        "common/src/VehiclePropertyStore.cpp",
         "common/src/VehicleUtils.cpp",
     ],
 }
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
index 0a243fe..6a02cf3 100644
--- 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
@@ -19,10 +19,11 @@
 
 #include <cstdint>
 #include <unordered_map>
+#include <map>
 #include <memory>
 #include <mutex>
 
-#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
+#include <android/hardware/automotive/vehicle/2.0/types.h>
 
 namespace android {
 namespace hardware {
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 81f3198..a85cdf0 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
@@ -17,8 +17,7 @@
 #ifndef android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_
 #define android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_
 
-#include <android/hardware/automotive/vehicle/2.0/types.h>
-#include <vhal_v2_0/VehicleUtils.h>
+#include "PropertyUtils.h"
 
 #include <map>
 
@@ -29,179 +28,6 @@
 namespace V2_0 {
 
 namespace impl {
-//
-// Some handy constants to avoid conversions from enum to int.
-constexpr int ABS_ACTIVE = (int)VehicleProperty::ABS_ACTIVE;
-constexpr int AP_POWER_STATE_REQ = (int)VehicleProperty::AP_POWER_STATE_REQ;
-constexpr int AP_POWER_STATE_REPORT = (int)VehicleProperty::AP_POWER_STATE_REPORT;
-constexpr int DOOR_1_LEFT = (int)VehicleAreaDoor::ROW_1_LEFT;
-constexpr int DOOR_1_RIGHT = (int)VehicleAreaDoor::ROW_1_RIGHT;
-constexpr int DOOR_2_LEFT = (int)VehicleAreaDoor::ROW_2_LEFT;
-constexpr int DOOR_2_RIGHT = (int)VehicleAreaDoor::ROW_2_RIGHT;
-constexpr int DOOR_REAR = (int)VehicleAreaDoor::REAR;
-constexpr int WINDOW_1_LEFT = (int)VehicleAreaWindow::ROW_1_LEFT;
-constexpr int WINDOW_1_RIGHT = (int)VehicleAreaWindow::ROW_1_RIGHT;
-constexpr int WINDOW_2_LEFT = (int)VehicleAreaWindow::ROW_2_LEFT;
-constexpr int WINDOW_2_RIGHT = (int)VehicleAreaWindow::ROW_2_RIGHT;
-constexpr int WINDOW_ROOF_TOP_1 = (int)VehicleAreaWindow::ROOF_TOP_1;
-constexpr int FAN_DIRECTION_FACE = (int)VehicleHvacFanDirection::FACE;
-constexpr int FAN_DIRECTION_FLOOR = (int)VehicleHvacFanDirection::FLOOR;
-constexpr int OBD2_LIVE_FRAME = (int)VehicleProperty::OBD2_LIVE_FRAME;
-constexpr int OBD2_FREEZE_FRAME = (int)VehicleProperty::OBD2_FREEZE_FRAME;
-constexpr int OBD2_FREEZE_FRAME_INFO = (int)VehicleProperty::OBD2_FREEZE_FRAME_INFO;
-constexpr int OBD2_FREEZE_FRAME_CLEAR = (int)VehicleProperty::OBD2_FREEZE_FRAME_CLEAR;
-constexpr int TRACTION_CONTROL_ACTIVE = (int)VehicleProperty::TRACTION_CONTROL_ACTIVE;
-constexpr int VEHICLE_MAP_SERVICE = (int)VehicleProperty::VEHICLE_MAP_SERVICE;
-constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK;
-constexpr int ALL_WHEELS =
-    (int)(VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT |
-          VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR);
-constexpr int SEAT_1_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT);
-constexpr int SEAT_1_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT);
-constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT |
-                                VehicleAreaSeat::ROW_2_CENTER);
-constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT);
-constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT;
-constexpr int VENDOR_EXTENSION_BOOLEAN_PROPERTY =
-    (int)(0x101 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::BOOLEAN | VehicleArea::DOOR);
-constexpr int VENDOR_EXTENSION_FLOAT_PROPERTY =
-    (int)(0x102 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::FLOAT | VehicleArea::SEAT);
-constexpr int VENDOR_EXTENSION_INT_PROPERTY =
-    (int)(0x103 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::INT32 | VehicleArea::WINDOW);
-constexpr int VENDOR_EXTENSION_STRING_PROPERTY =
-    (int)(0x104 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::STRING | VehicleArea::GLOBAL);
-constexpr int FUEL_DOOR_REAR_LEFT = (int)PortLocationType::REAR_LEFT;
-constexpr int CHARGE_PORT_FRONT_LEFT = (int)PortLocationType::FRONT_LEFT;
-constexpr int CHARGE_PORT_REAR_LEFT = (int)PortLocationType::REAR_LEFT;
-constexpr int LIGHT_STATE_ON = (int)VehicleLightState::ON;
-constexpr int LIGHT_SWITCH_AUTO = (int)VehicleLightSwitch::AUTOMATIC;
-constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT;
-constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT;
-constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR;
-constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR;
-
-/**
- * This property is used for test purpose to generate fake events. Here is the test package that
- * is referencing this property definition: packages/services/Car/tests/vehiclehal_test
- */
-const int32_t kGenerateFakeDataControllingProperty =
-    0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
-
-/**
- * This property is used for test purpose to set properties' value from vehicle.
- * For example: Mocking hard button press triggering a HVAC fan speed change.
- * Android set kSetPropertyFromVehicleForTest with an array of integer {HVAC_FAN_SPEED, value of
- * fan speed} and a long value indicates the timestamp of the events .
- * It only works with integer type properties.
- */
-const int32_t kSetIntPropertyFromVehicleForTest =
-        0x1112 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
-/**
- * This property is used for test purpose to set properties' value from vehicle.
- * It only works with float type properties.
- */
-const int32_t kSetFloatPropertyFromVehicleForTest =
-        0x1113 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
-/**
- * This property is used for test purpose to set properties' value from vehicle.
- * It only works with boolean type properties.
- */
-const int32_t kSetBooleanPropertyFromVehicleForTest =
-        0x1114 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
-
-/**
- * This property is used for test purpose. End to end tests use this property to test set and get
- * method for MIXED type properties.
- */
-const int32_t kMixedTypePropertyForTest =
-        0x1111 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
-
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
-/**
- * Converts the system property to the vendor property.
- * WARNING: This is only for the end-to-end testing, Should NOT include in the
- * user build */
-inline constexpr int32_t toVendor(VehicleProperty prop) {
-    return (toInt(prop) & ~toInt(VehiclePropertyGroup::MASK)) | VehiclePropertyGroup::VENDOR;
-}
-
-/**
- * These properties are used for the end-to-end testing of ClusterHomeService.
- */
-constexpr int32_t VENDOR_CLUSTER_SWITCH_UI = toVendor(VehicleProperty::CLUSTER_SWITCH_UI);
-constexpr int32_t VENDOR_CLUSTER_DISPLAY_STATE = toVendor(VehicleProperty::CLUSTER_DISPLAY_STATE);
-constexpr int32_t VENDOR_CLUSTER_REPORT_STATE = toVendor(VehicleProperty::CLUSTER_REPORT_STATE);
-constexpr int32_t VENDOR_CLUSTER_REQUEST_DISPLAY =
-        toVendor(VehicleProperty::CLUSTER_REQUEST_DISPLAY);
-constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE =
-        toVendor(VehicleProperty::CLUSTER_NAVIGATION_STATE);
-#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
-
-/**
- * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty.
- * All those commands can be send independently with each other. And each will override the one sent
- * previously.
- *
- * The controlling property has the following format:
- *
- *     int32Values[0] - command enum defined in FakeDataCommand
- *
- * The format of the arguments is defined for each command type as below:
- */
-enum class FakeDataCommand : int32_t {
-    /**
-     * Starts linear fake data generation. Caller must provide additional data:
-     *     int32Values[1] - vehicle property to which command applies
-     *     int64Values[0] - periodic interval in nanoseconds
-     *     floatValues[0] - initial value
-     *     floatValues[1] - dispersion defines the min/max value relative to initial value, where
-     *                      max = initial_value + dispersion, min = initial_value - dispersion.
-     *                      Dispersion should be non-negative, otherwise the behavior is undefined.
-     *     floatValues[2] - increment, with every timer tick the value will be incremented by this
-     *                      amount. When reaching to max value, the current value will be set to
-     *                      min. It should be non-negative, otherwise the behavior is undefined.
-     */
-    StartLinear = 0,
-
-    /** Stops linear fake data generation that was triggered by StartLinear commands.
-     *     int32Values[1] - vehicle property to which command applies. VHAL will stop the
-     *                      corresponding linear generation for that property.
-     */
-    StopLinear = 1,
-
-    /**
-     * Starts JSON-based fake data generation. It iterates through JSON-encoded VHAL events from a
-     * file and inject them to VHAL. The iteration can be repeated multiple times or infinitely.
-     * Caller must provide additional data:
-     *     int32Values[1] - number of iterations. If it is not provided or -1. The iteration will be
-     *                      repeated infinite times.
-     *     stringValue    - path to the fake values JSON file
-     */
-    StartJson = 2,
-
-    /**
-     * Stops JSON-based fake data generation. As multiple JSON-based generation can happen at the
-     * same time. Caller must provide the path of fake value JSON file to stop the corresponding
-     * generation:
-     *     stringValue    - path to the fake values JSON file
-     */
-    StopJson = 3,
-
-    /**
-     * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every
-     * key-press). We set the enum with high number to leave space for future start/stop commands.
-     * Caller must provide the following data:
-     *     int32Values[2] - Android key code
-     *     int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see
-     *                      VehicleDisplay)
-     */
-    KeyPress = 100,
-};
-
-const int32_t kHvacPowerProperties[] = {
-    toInt(VehicleProperty::HVAC_FAN_SPEED),
-    toInt(VehicleProperty::HVAC_FAN_DIRECTION),
-};
 
 struct ConfigDeclaration {
     VehiclePropConfig config;
@@ -249,14 +75,6 @@
 
         {.config =
                  {
-                         .prop = toInt(VehicleProperty::INFO_DRIVER_SEAT),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::STATIC,
-                 },
-         .initialValue = {.int32Values = {SEAT_1_LEFT}}},
-
-        {.config =
-                 {
                          .prop = toInt(VehicleProperty::INFO_FUEL_DOOR_LOCATION),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::STATIC,
@@ -1201,7 +1019,7 @@
         {
                 .config =
                         {
-                                .prop = toInt(VehicleProperty::UNIX_TIME),
+                                .prop = toInt(VehicleProperty::EPOCH_TIME),
                                 .access = VehiclePropertyAccess::READ_WRITE,
                                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
                         },
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
index ed3f4a2..eae58d0 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -21,7 +21,6 @@
 #include <android-base/logging.h>
 #include <utils/SystemClock.h>
 
-#include "DefaultConfig.h"
 #include "EmulatedVehicleConnector.h"
 #include "JsonFakeValueGenerator.h"
 #include "LinearFakeValueGenerator.h"
@@ -39,6 +38,10 @@
     return &mEmulatedUserHal;
 }
 
+void EmulatedVehicleConnector::triggerSendAllValues() {
+    sendAllValuesToClient();
+}
+
 StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value,
                                                    bool updateStatus) {
     if (mEmulatedUserHal.isSupported(value.prop)) {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
index 4c6c661..31ac7d8 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
@@ -33,11 +33,13 @@
 
 class EmulatedVehicleConnector : public IPassThroughConnector<VehicleHalClient, VehicleHalServer> {
   public:
-    EmulatedVehicleConnector() {}
+    EmulatedVehicleConnector() = default;
 
     EmulatedUserHal* getEmulatedUserHal();
 
     // Methods from VehicleHalServer
+    void triggerSendAllValues() override;
+
     StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
 
     bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
index 1608e52..e8b79dc 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp
@@ -105,9 +105,6 @@
       mVehicleClient(client),
       mEmulatedUserHal(emulatedUserHal) {
     initStaticConfig();
-    for (size_t i = 0; i < arraysize(kVehicleProperties); i++) {
-        mPropStore->registerProperty(kVehicleProperties[i].config);
-    }
     mVehicleClient->registerPropertyValueCallback(std::bind(&EmulatedVehicleHal::onPropertyValue,
                                                             this, std::placeholders::_1,
                                                             std::placeholders::_2));
@@ -180,7 +177,13 @@
                 v = getValuePool()->obtain(*internalPropValue);
             }
 
-            *outStatus = v != nullptr ? StatusCode::OK : StatusCode::INVALID_ARG;
+            if (!v) {
+                *outStatus = StatusCode::INVALID_ARG;
+            } else if (v->status == VehiclePropertyStatus::AVAILABLE) {
+                *outStatus = StatusCode::OK;
+            } else {
+                *outStatus = StatusCode::TRY_AGAIN;
+            }
             break;
     }
     if (v.get()) {
@@ -280,57 +283,41 @@
 void EmulatedVehicleHal::onCreate() {
     static constexpr bool shouldUpdateStatus = true;
 
-    for (auto& it : kVehicleProperties) {
-        VehiclePropConfig cfg = it.config;
-        int32_t numAreas = cfg.areaConfigs.size();
+    auto configs = mVehicleClient->getAllPropertyConfig();
 
+    for (const auto& cfg : configs) {
         if (isDiagnosticProperty(cfg)) {
             // do not write an initial empty value for the diagnostic properties
             // as we will initialize those separately.
             continue;
         }
 
-        // A global property will have only a single area
-        if (isGlobalProp(cfg.prop)) {
-            numAreas = 1;
-        }
+        int32_t numAreas = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs.size();
 
         for (int i = 0; i < numAreas; i++) {
-            int32_t curArea;
-
-            if (isGlobalProp(cfg.prop)) {
-                curArea = 0;
-            } else {
-                curArea = cfg.areaConfigs[i].areaId;
-            }
+            int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
 
             // Create a separate instance for each individual zone
             VehiclePropValue prop = {
                     .areaId = curArea,
                     .prop = cfg.prop,
+                    .status = VehiclePropertyStatus::UNAVAILABLE,
             };
 
-            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;
-                if (mInitVhalValueOverride) {
-                    for (auto& itOverride : mVehiclePropertiesOverride) {
-                        if (itOverride.prop == cfg.prop) {
-                            prop.value = itOverride.value;
-                        }
+            if (mInitVhalValueOverride) {
+                for (auto& itOverride : mVehiclePropertiesOverride) {
+                    if (itOverride.prop == cfg.prop) {
+                        prop.status = VehiclePropertyStatus::AVAILABLE;
+                        prop.value = itOverride.value;
                     }
                 }
             }
             mPropStore->writeValue(prop, shouldUpdateStatus);
         }
     }
+
+    mVehicleClient->triggerSendAllValues();
+
     initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
     initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
     mInEmulator = isInEmulator();
@@ -414,8 +401,8 @@
 }
 
 void EmulatedVehicleHal::initStaticConfig() {
-    for (auto&& it = std::begin(kVehicleProperties); it != std::end(kVehicleProperties); ++it) {
-        const auto& cfg = it->config;
+    auto configs = mVehicleClient->getAllPropertyConfig();
+    for (auto&& cfg : configs) {
         VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
 
         switch (cfg.prop) {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
index 5c67641..7871c7b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h
@@ -29,10 +29,10 @@
 #include <vhal_v2_0/VehicleHal.h>
 #include "vhal_v2_0/VehiclePropertyStore.h"
 
-#include "DefaultConfig.h"
 #include "EmulatedUserHal.h"
 #include "EmulatedVehicleConnector.h"
 #include "GeneratorHub.h"
+#include "PropertyUtils.h"
 #include "VehicleEmulator.h"
 
 namespace android {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h
new file mode 100644
index 0000000..d5f6a18
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+#include <vhal_v2_0/VehicleUtils.h>
+
+namespace android::hardware::automotive::vehicle::V2_0::impl {
+
+// Some handy constants to avoid conversions from enum to int.
+constexpr int ABS_ACTIVE = (int)VehicleProperty::ABS_ACTIVE;
+constexpr int AP_POWER_STATE_REQ = (int)VehicleProperty::AP_POWER_STATE_REQ;
+constexpr int AP_POWER_STATE_REPORT = (int)VehicleProperty::AP_POWER_STATE_REPORT;
+constexpr int DOOR_1_LEFT = (int)VehicleAreaDoor::ROW_1_LEFT;
+constexpr int DOOR_1_RIGHT = (int)VehicleAreaDoor::ROW_1_RIGHT;
+constexpr int DOOR_2_LEFT = (int)VehicleAreaDoor::ROW_2_LEFT;
+constexpr int DOOR_2_RIGHT = (int)VehicleAreaDoor::ROW_2_RIGHT;
+constexpr int DOOR_REAR = (int)VehicleAreaDoor::REAR;
+constexpr int WINDOW_1_LEFT = (int)VehicleAreaWindow::ROW_1_LEFT;
+constexpr int WINDOW_1_RIGHT = (int)VehicleAreaWindow::ROW_1_RIGHT;
+constexpr int WINDOW_2_LEFT = (int)VehicleAreaWindow::ROW_2_LEFT;
+constexpr int WINDOW_2_RIGHT = (int)VehicleAreaWindow::ROW_2_RIGHT;
+constexpr int WINDOW_ROOF_TOP_1 = (int)VehicleAreaWindow::ROOF_TOP_1;
+constexpr int FAN_DIRECTION_FACE = (int)VehicleHvacFanDirection::FACE;
+constexpr int FAN_DIRECTION_FLOOR = (int)VehicleHvacFanDirection::FLOOR;
+constexpr int OBD2_LIVE_FRAME = (int)VehicleProperty::OBD2_LIVE_FRAME;
+constexpr int OBD2_FREEZE_FRAME = (int)VehicleProperty::OBD2_FREEZE_FRAME;
+constexpr int OBD2_FREEZE_FRAME_INFO = (int)VehicleProperty::OBD2_FREEZE_FRAME_INFO;
+constexpr int OBD2_FREEZE_FRAME_CLEAR = (int)VehicleProperty::OBD2_FREEZE_FRAME_CLEAR;
+constexpr int TRACTION_CONTROL_ACTIVE = (int)VehicleProperty::TRACTION_CONTROL_ACTIVE;
+constexpr int VEHICLE_MAP_SERVICE = (int)VehicleProperty::VEHICLE_MAP_SERVICE;
+constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK;
+constexpr int ALL_WHEELS =
+    (int)(VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT |
+          VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR);
+constexpr int SEAT_1_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT);
+constexpr int SEAT_1_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT);
+constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT |
+                                VehicleAreaSeat::ROW_2_CENTER);
+constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT);
+constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT;
+constexpr int VENDOR_EXTENSION_BOOLEAN_PROPERTY =
+    (int)(0x101 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::BOOLEAN | VehicleArea::DOOR);
+constexpr int VENDOR_EXTENSION_FLOAT_PROPERTY =
+    (int)(0x102 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::FLOAT | VehicleArea::SEAT);
+constexpr int VENDOR_EXTENSION_INT_PROPERTY =
+    (int)(0x103 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::INT32 | VehicleArea::WINDOW);
+constexpr int VENDOR_EXTENSION_STRING_PROPERTY =
+    (int)(0x104 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::STRING | VehicleArea::GLOBAL);
+constexpr int FUEL_DOOR_REAR_LEFT = (int)PortLocationType::REAR_LEFT;
+constexpr int CHARGE_PORT_FRONT_LEFT = (int)PortLocationType::FRONT_LEFT;
+constexpr int CHARGE_PORT_REAR_LEFT = (int)PortLocationType::REAR_LEFT;
+constexpr int LIGHT_STATE_ON = (int)VehicleLightState::ON;
+constexpr int LIGHT_SWITCH_AUTO = (int)VehicleLightSwitch::AUTOMATIC;
+constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT;
+constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT;
+constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR;
+constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR;
+
+/**
+ * This property is used for test purpose to generate fake events. Here is the test package that
+ * is referencing this property definition: packages/services/Car/tests/vehiclehal_test
+ */
+const int32_t kGenerateFakeDataControllingProperty =
+    0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
+
+/**
+ * This property is used for test purpose to set properties' value from vehicle.
+ * For example: Mocking hard button press triggering a HVAC fan speed change.
+ * Android set kSetPropertyFromVehicleForTest with an array of integer {HVAC_FAN_SPEED, value of
+ * fan speed} and a long value indicates the timestamp of the events .
+ * It only works with integer type properties.
+ */
+const int32_t kSetIntPropertyFromVehicleForTest =
+        0x1112 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
+/**
+ * This property is used for test purpose to set properties' value from vehicle.
+ * It only works with float type properties.
+ */
+const int32_t kSetFloatPropertyFromVehicleForTest =
+        0x1113 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
+/**
+ * This property is used for test purpose to set properties' value from vehicle.
+ * It only works with boolean type properties.
+ */
+const int32_t kSetBooleanPropertyFromVehicleForTest =
+        0x1114 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
+
+/**
+ * This property is used for test purpose. End to end tests use this property to test set and get
+ * method for MIXED type properties.
+ */
+const int32_t kMixedTypePropertyForTest =
+        0x1111 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED;
+
+#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+/**
+ * Converts the system property to the vendor property.
+ * WARNING: This is only for the end-to-end testing, Should NOT include in the
+ * user build */
+inline constexpr int32_t toVendor(VehicleProperty prop) {
+    return (toInt(prop) & ~toInt(VehiclePropertyGroup::MASK)) | VehiclePropertyGroup::VENDOR;
+}
+
+/**
+ * These properties are used for the end-to-end testing of ClusterHomeService.
+ */
+constexpr int32_t VENDOR_CLUSTER_SWITCH_UI = toVendor(VehicleProperty::CLUSTER_SWITCH_UI);
+constexpr int32_t VENDOR_CLUSTER_DISPLAY_STATE = toVendor(VehicleProperty::CLUSTER_DISPLAY_STATE);
+constexpr int32_t VENDOR_CLUSTER_REPORT_STATE = toVendor(VehicleProperty::CLUSTER_REPORT_STATE);
+constexpr int32_t VENDOR_CLUSTER_REQUEST_DISPLAY =
+        toVendor(VehicleProperty::CLUSTER_REQUEST_DISPLAY);
+constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE =
+        toVendor(VehicleProperty::CLUSTER_NAVIGATION_STATE);
+#endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+
+/**
+ * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty.
+ * All those commands can be send independently with each other. And each will override the one sent
+ * previously.
+ *
+ * The controlling property has the following format:
+ *
+ *     int32Values[0] - command enum defined in FakeDataCommand
+ *
+ * The format of the arguments is defined for each command type as below:
+ */
+enum class FakeDataCommand : int32_t {
+    /**
+     * Starts linear fake data generation. Caller must provide additional data:
+     *     int32Values[1] - vehicle property to which command applies
+     *     int64Values[0] - periodic interval in nanoseconds
+     *     floatValues[0] - initial value
+     *     floatValues[1] - dispersion defines the min/max value relative to initial value, where
+     *                      max = initial_value + dispersion, min = initial_value - dispersion.
+     *                      Dispersion should be non-negative, otherwise the behavior is undefined.
+     *     floatValues[2] - increment, with every timer tick the value will be incremented by this
+     *                      amount. When reaching to max value, the current value will be set to
+     *                      min. It should be non-negative, otherwise the behavior is undefined.
+     */
+    StartLinear = 0,
+
+    /** Stops linear fake data generation that was triggered by StartLinear commands.
+     *     int32Values[1] - vehicle property to which command applies. VHAL will stop the
+     *                      corresponding linear generation for that property.
+     */
+    StopLinear = 1,
+
+    /**
+     * Starts JSON-based fake data generation. It iterates through JSON-encoded VHAL events from a
+     * file and inject them to VHAL. The iteration can be repeated multiple times or infinitely.
+     * Caller must provide additional data:
+     *     int32Values[1] - number of iterations. If it is not provided or -1. The iteration will be
+     *                      repeated infinite times.
+     *     stringValue    - path to the fake values JSON file
+     */
+    StartJson = 2,
+
+    /**
+     * Stops JSON-based fake data generation. As multiple JSON-based generation can happen at the
+     * same time. Caller must provide the path of fake value JSON file to stop the corresponding
+     * generation:
+     *     stringValue    - path to the fake values JSON file
+     */
+    StopJson = 3,
+
+    /**
+     * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every
+     * key-press). We set the enum with high number to leave space for future start/stop commands.
+     * Caller must provide the following data:
+     *     int32Values[2] - Android key code
+     *     int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see
+     *                      VehicleDisplay)
+     */
+    KeyPress = 100,
+};
+
+const int32_t kHvacPowerProperties[] = {
+    toInt(VehicleProperty::HVAC_FAN_SPEED),
+    toInt(VehicleProperty::HVAC_FAN_DIRECTION),
+};
+
+}  // namespace android::hardware::automotive::vehicle::V2_0::impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h
index 6559e2a..81dfca1 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h
@@ -27,6 +27,10 @@
     // Type of callback function for handling the new property values
     using PropertyCallBackType = std::function<void(const VehiclePropValue&, bool updateStatus)>;
 
+    // The server will call sendAllValuesToClient, onPropertyValue will be called when values are
+    // received.
+    virtual void triggerSendAllValues() = 0;
+
     // Method from IVehicleClient
     void onPropertyValue(const VehiclePropValue& value, bool updateStatus) override;
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
index 6b87052..57dd7d4 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
@@ -30,6 +30,66 @@
 
 namespace android::hardware::automotive::vehicle::V2_0::impl {
 
+static bool isDiagnosticProperty(VehiclePropConfig propConfig) {
+    switch (propConfig.prop) {
+        case OBD2_LIVE_FRAME:
+        case OBD2_FREEZE_FRAME:
+        case OBD2_FREEZE_FRAME_CLEAR:
+        case OBD2_FREEZE_FRAME_INFO:
+            return true;
+    }
+    return false;
+}
+
+VehicleHalServer::VehicleHalServer() {
+    constexpr bool shouldUpdateStatus = true;
+
+    for (auto& it : kVehicleProperties) {
+        VehiclePropConfig cfg = it.config;
+
+        mServerSidePropStore.registerProperty(cfg);
+
+        if (isDiagnosticProperty(cfg)) {
+            continue;
+        }
+
+        // A global property will have only a single area
+        int32_t numAreas = isGlobalProp(cfg.prop) ? 1 : cfg.areaConfigs.size();
+
+        for (int i = 0; i < numAreas; i++) {
+            int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
+
+            // Create a separate instance for each individual zone
+            VehiclePropValue prop = {
+                    .areaId = curArea,
+                    .prop = cfg.prop,
+            };
+
+            if (it.initialAreaValues.empty()) {
+                prop.value = it.initialValue;
+            } else if (auto valueForAreaIt = it.initialAreaValues.find(curArea);
+                       valueForAreaIt != it.initialAreaValues.end()) {
+                prop.value = valueForAreaIt->second;
+            } else {
+                LOG(WARNING) << __func__ << " failed to get default value for"
+                             << " prop 0x" << std::hex << cfg.prop << " area 0x" << std::hex
+                             << curArea;
+                prop.status = VehiclePropertyStatus::UNAVAILABLE;
+            }
+
+            mServerSidePropStore.writeValue(prop, shouldUpdateStatus);
+        }
+    }
+}
+
+void VehicleHalServer::sendAllValuesToClient() {
+    constexpr bool update_status = true;
+    auto values = mServerSidePropStore.readAllValues();
+    for (const auto& value : values) {
+        onPropertyValueFromCar(value, update_status);
+    }
+}
+
 GeneratorHub* VehicleHalServer::getGenerator() {
     return &mGeneratorHub;
 }
@@ -55,19 +115,13 @@
     if (updatedPropValue) {
         updatedPropValue->timestamp = value.timestamp;
         updatedPropValue->status = VehiclePropertyStatus::AVAILABLE;
+        mServerSidePropStore.writeValue(*updatedPropValue, updateStatus);
         onPropertyValueFromCar(*updatedPropValue, updateStatus);
     }
 }
 
 std::vector<VehiclePropConfig> VehicleHalServer::onGetAllPropertyConfig() const {
-    std::vector<VehiclePropConfig> vehiclePropConfigs;
-    constexpr size_t numOfVehiclePropConfigs =
-            sizeof(kVehicleProperties) / sizeof(kVehicleProperties[0]);
-    vehiclePropConfigs.reserve(numOfVehiclePropConfigs);
-    for (auto& it : kVehicleProperties) {
-        vehiclePropConfigs.emplace_back(it.config);
-    }
-    return vehiclePropConfigs;
+    return mServerSidePropStore.getAllConfigs();
 }
 
 StatusCode VehicleHalServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) {
@@ -278,6 +332,7 @@
     auto updatedPropValue = getValuePool()->obtain(value);
     updatedPropValue->timestamp = elapsedRealtimeNano();
 
+    mServerSidePropStore.writeValue(*updatedPropValue, updateStatus);
     onPropertyValueFromCar(*updatedPropValue, updateStatus);
     return StatusCode::OK;
 }
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
index 117eadb..be88cd9 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <vhal_v2_0/VehicleObjectPool.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
 #include <vhal_v2_0/VehicleServer.h>
 
 #include "GeneratorHub.h"
@@ -28,6 +29,10 @@
 // scenario, the server may be run on a different OS than Android.
 class VehicleHalServer : public IVehicleServer {
   public:
+    VehicleHalServer();
+
+    void sendAllValuesToClient();
+
     // Methods from IVehicleServer
 
     std::vector<VehiclePropConfig> onGetAllPropertyConfig() const override;
@@ -58,6 +63,7 @@
             std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)};
 
     VehiclePropValuePool* mValuePool{nullptr};
+    VehiclePropertyStore mServerSidePropStore;
 };
 
 }  // namespace android::hardware::automotive::vehicle::V2_0::impl
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index e22f9fa..6bfda32 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -1446,7 +1446,7 @@
      * @access VehiclePropertyAccess:READ_WRITE
      * @unit VehicleUnit:MILLI_SECS
      */
-    UNIX_TIME = (
+    EPOCH_TIME = (
         0x0606
         | VehiclePropertyGroup:SYSTEM
         | VehiclePropertyType:INT64
diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
index c548fe5..8443336 100644
--- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
@@ -40,8 +40,7 @@
             promise.set_value();
         })));
 
-        auto status = future.wait_for(1s);
-        EXPECT_EQ(status, std::future_status::ready);
+        future.wait();
     }
 }
 
@@ -56,12 +55,11 @@
         // Notify that the task has started.
         promise.set_value();
         // Block for a "very long" time.
-        std::this_thread::sleep_for(2s);
+        std::this_thread::sleep_for(1s);
     })));
 
     // Make sure the long-running task began executing.
-    auto status = future.wait_for(1s);
-    ASSERT_EQ(status, std::future_status::ready);
+    future.wait();
 
     // The first task is already being worked on, which means the queue must be empty.
     // Fill the worker's queue to the maximum.
@@ -91,8 +89,7 @@
     // Schedule a special task to signal when all of the tasks are finished.
     worker.schedule(
             Callable::from([promise = std::move(promise)]() mutable { promise.set_value(); }));
-    auto status = future.wait_for(1s);
-    ASSERT_EQ(status, std::future_status::ready);
+    future.wait();
 
     ASSERT_EQ(results.size(), NUM_TASKS);
     EXPECT_TRUE(std::is_sorted(results.begin(), results.end()));
@@ -115,8 +112,7 @@
         })));
 
         // The first task should start executing.
-        auto status = future1.wait_for(1s);
-        ASSERT_EQ(status, std::future_status::ready);
+        future1.wait();
 
         // The second task should schedule successfully.
         ASSERT_TRUE(
@@ -128,8 +124,7 @@
     }
 
     // The second task should never execute.
-    auto status = future2.wait_for(1s);
-    ASSERT_EQ(status, std::future_status::ready);
+    future2.wait();
     // The future is expected to be ready but contain an exception.
     // Cannot use ASSERT_THROW because exceptions are disabled in this codebase.
     // ASSERT_THROW(future2.get(), std::future_error);
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index deb420d..0ec9fe3 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -997,7 +997,8 @@
                 frameNumber(0),
                 partialResultCount(0),
                 errorStreamId(-1),
-                hasInputBuffer(false) {}
+                hasInputBuffer(false),
+                collectedResult(1, 10) {}
 
         InFlightRequest(ssize_t numBuffers, bool hasInput,
                 bool partialResults, uint32_t partialCount,
@@ -1013,7 +1014,8 @@
                 frameNumber(0),
                 partialResultCount(0),
                 errorStreamId(-1),
-                hasInputBuffer(hasInput) {}
+                hasInputBuffer(hasInput),
+                collectedResult(1, 10) {}
 
         InFlightRequest(ssize_t numBuffers, bool hasInput,
                 bool partialResults, uint32_t partialCount,
@@ -1031,6 +1033,7 @@
                 partialResultCount(0),
                 errorStreamId(-1),
                 hasInputBuffer(hasInput),
+                collectedResult(1, 10),
                 expectedPhysicalResults(extraPhysicalResult) {}
     };
 
@@ -1313,7 +1316,7 @@
                 reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
         const camera_metadata_t* collectedMetadata = request->collectedResult.getAndLock();
         camera_metadata_ro_entry_t searchEntry, foundEntry;
-        for (size_t i = 0; i < get_camera_metadata_size(partialMetadata); i++) {
+        for (size_t i = 0; i < get_camera_metadata_entry_count(partialMetadata); i++) {
             if (0 != get_camera_metadata_ro_entry(partialMetadata, i, &searchEntry)) {
                 ADD_FAILURE();
                 request->collectedResult.unlock(collectedMetadata);
diff --git a/current.txt b/current.txt
index 8432791..3102972 100644
--- a/current.txt
+++ b/current.txt
@@ -785,6 +785,8 @@
 550619f876cadbea1f718edce120f0e1dd4a6f4bd4c28b59d479677dc86b0aec android.hardware.neuralnetworks@1.3::types
 c3fec5bd470984402997f78a74b6511efc4063b270f2bd9ee7b78f48b683a1bb android.hardware.neuralnetworks@1.3::IDevice
 0fdfad62c2ec33b52e6687004e5a1971c02d10b93ee4d26df5ccff7ce032494a android.hardware.neuralnetworks@1.3::IPreparedModel
+b40c13f9a9affc806c778c1f8c78e90d4acb50f1d6a6be185d933d7a04b91c5b android.hardware.sensors@1.0::ISensors
+432086950205f5876da85dbd42004b0d0d05b429b9494b4f76a4d888758c5bd8 android.hardware.sensors@1.0::types
 e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
 b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types
 0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index f17336b..f57c599 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -464,12 +464,10 @@
     gnss_cb_->location_cbq_.reset();
 
     // Start of Low Power Mode test
-    SetPositionMode(kMinIntervalMsec, kLowPowerMode);
-
     // Don't expect true - as without AGPS access
     if (!StartAndCheckFirstLocation(/* strict= */ false,
-                                    /* min_interval_msec= */ 1000,
-                                    /* low_power_mode= */ false)) {
+                                    /* min_interval_msec= */ kMinIntervalMsec,
+                                    /* low_power_mode= */ kLowPowerMode)) {
         ALOGW("GetLocationLowPower test - no first low power location received.");
     }
 
diff --git a/identity/aidl/default/libeic/EicCbor.c b/identity/aidl/default/libeic/EicCbor.c
index fe131eb..0e2684f 100644
--- a/identity/aidl/default/libeic/EicCbor.c
+++ b/identity/aidl/default/libeic/EicCbor.c
@@ -114,7 +114,7 @@
         data[4] = size & 0xff;
         eicCborAppend(cbor, data, 5);
     } else {
-        data[0] = (majorType << 5) | 24;
+        data[0] = (majorType << 5) | 27;
         data[1] = (((uint64_t)size) >> 56) & 0xff;
         data[2] = (((uint64_t)size) >> 48) & 0xff;
         data[3] = (((uint64_t)size) >> 40) & 0xff;
diff --git a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
index e46cb48..0639da8 100644
--- a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -243,7 +243,9 @@
 
     EXPECT_EQ(ErrorCode::OK, result);
     EXPECT_EQ(2U, cert_chain.size());
-    if (dumpAttestations) dumpContent(bin2hex(cert_chain[0]));
+    if (dumpAttestations) {
+      for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_));
+    }
     auto [err, attestation] = parse_attestation_record(cert_chain[0]);
     ASSERT_EQ(ErrorCode::OK, err);
 
@@ -287,7 +289,9 @@
 
     EXPECT_EQ(ErrorCode::OK, result);
     EXPECT_EQ(2U, cert_chain.size());
-    if (dumpAttestations) dumpContent(bin2hex(cert_chain[0]));
+    if (dumpAttestations) {
+      for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_));
+    }
     auto [err, attestation] = parse_attestation_record(cert_chain[0]);
     ASSERT_EQ(ErrorCode::OK, err);
 
diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl
index 12d2042..66c8c8c 100644
--- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl
@@ -25,7 +25,7 @@
      */
     int id;
     /**
-     * Time since boot in milliseconds
+     * Time of data capture in milliseconds since boot (CLOCK_BOOTTIME clock)
      */
     long timestampMs;
     /**
@@ -38,4 +38,3 @@
      */
     EnergyConsumerAttribution[] attribution;
 }
-
diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
index d3e8f46..31fbaa8 100644
--- a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
+++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl
@@ -23,7 +23,7 @@
      */
     int id;
     /**
-     * Approximate time of data capture in millseconds since boot
+     * Time of data capture in milliseconds since boot (CLOCK_BOOTTIME clock)
      */
     long timestampMs;
     /**
@@ -35,4 +35,3 @@
      */
     long energyUWs;
 }
-
diff --git a/radio/1.0/vts/OWNERS b/radio/1.0/vts/OWNERS
index 2384317..9310f8e 100644
--- a/radio/1.0/vts/OWNERS
+++ b/radio/1.0/vts/OWNERS
@@ -1,8 +1,7 @@
 # Telephony team
 amitmahajan@google.com
-sanketpadawe@google.com
 shuoq@google.com
+jackyu@google.com
 
 # VTS team
-yuexima@google.com
-yim@google.com
+dshi@google.com
diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp
index fc37201..5b31acc 100644
--- a/radio/1.0/vts/functional/vts_test_util.cpp
+++ b/radio/1.0/vts/functional/vts_test_util.cpp
@@ -83,6 +83,13 @@
     return hasFeature;
 }
 
+bool isSsSsEnabled() {
+    // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
+    // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
+    // by definition the empty string "" is a substring of any string).
+    return !isDsDsEnabled() && !isTsTsEnabled();
+}
+
 bool isDsDsEnabled() {
     return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "dsds");
 }
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index eeb1d29..fa338a3 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -80,12 +80,17 @@
 bool deviceSupportsFeature(const char* feature);
 
 /*
- * Check if device is in DSDS.
+ * Check if device is in SsSs (Single SIM Single Standby).
+ */
+bool isSsSsEnabled();
+
+/*
+ * Check if device is in DSDS (Dual SIM Dual Standby).
  */
 bool isDsDsEnabled();
 
 /*
- * Check if device is in TSTS.
+ * Check if device is in TSTS (Triple SIM Triple Standby).
  */
 bool isTsTsEnabled();
 
diff --git a/radio/1.1/vts/OWNERS b/radio/1.1/vts/OWNERS
index 2384317..a07c917 100644
--- a/radio/1.1/vts/OWNERS
+++ b/radio/1.1/vts/OWNERS
@@ -1,8 +1 @@
-# Telephony team
-amitmahajan@google.com
-sanketpadawe@google.com
-shuoq@google.com
-
-# VTS team
-yuexima@google.com
-yim@google.com
+include ../../1.0/vts/OWNERS
diff --git a/radio/1.2/vts/OWNERS b/radio/1.2/vts/OWNERS
index 245d9d4..a07c917 100644
--- a/radio/1.2/vts/OWNERS
+++ b/radio/1.2/vts/OWNERS
@@ -1,9 +1 @@
-# Telephony team
-amitmahajan@google.com
-sanketpadawe@google.com
-shuoq@google.com
-sasindran@google.com
-
-# VTS team
-yuexima@google.com
-yim@google.com
+include ../../1.0/vts/OWNERS
diff --git a/radio/1.3/vts/OWNERS b/radio/1.3/vts/OWNERS
index d642064..a07c917 100644
--- a/radio/1.3/vts/OWNERS
+++ b/radio/1.3/vts/OWNERS
@@ -1,10 +1 @@
-# Telephony team
-amitmahajan@google.com
-sanketpadawe@google.com
-shuoq@google.com
-sasindran@google.com
-nazaninb@google.com
-
-# VTS team
-yuexima@google.com
-yim@google.com
+include ../../1.0/vts/OWNERS
diff --git a/radio/1.4/vts/OWNERS b/radio/1.4/vts/OWNERS
index fd69f36..a07c917 100644
--- a/radio/1.4/vts/OWNERS
+++ b/radio/1.4/vts/OWNERS
@@ -1,8 +1 @@
-# Telephony team
-amitmahajan@google.com
-shuoq@google.com
-sasindran@google.com
-
-# VTS team
-yuexima@google.com
-yim@google.com
\ No newline at end of file
+include ../../1.0/vts/OWNERS
diff --git a/radio/1.5/vts/OWNERS b/radio/1.5/vts/OWNERS
index 3629a6c..a07c917 100644
--- a/radio/1.5/vts/OWNERS
+++ b/radio/1.5/vts/OWNERS
@@ -1,10 +1 @@
-# Telephony team
-refuhoo@google.com
-amitmahajan@google.com
-jackyu@google.com
-fionaxu@google.com
-# more to add
-
-# VTS team
-yuexima@google.com
-dshi@google.com
\ No newline at end of file
+include ../../1.0/vts/OWNERS
diff --git a/radio/1.6/vts/OWNERS b/radio/1.6/vts/OWNERS
index 3629a6c..a07c917 100644
--- a/radio/1.6/vts/OWNERS
+++ b/radio/1.6/vts/OWNERS
@@ -1,10 +1 @@
-# Telephony team
-refuhoo@google.com
-amitmahajan@google.com
-jackyu@google.com
-fionaxu@google.com
-# more to add
-
-# VTS team
-yuexima@google.com
-dshi@google.com
\ No newline at end of file
+include ../../1.0/vts/OWNERS
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 037d747..5af007e 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -512,6 +512,8 @@
                  ::android::hardware::radio::V1_6::RadioError::NONE,
                  ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS}));
     }
+
+    sleep(1);
 }
 
 /*
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp
index 4222441..8c99d92 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp
@@ -45,10 +45,8 @@
                ::android::hardware::radio::V1_0::RadioError::NONE) {
         static const std::regex kOperatorNumericRe("^[0-9]{5,6}$");
         for (OperatorInfo info : radioRsp_v1_6->networkInfos) {
-            if (info.operatorNumeric != nullptr) {
-                ASSERT_TRUE(
-                        std::regex_match(std::string(info.operatorNumeric), kOperatorNumericRe));
-            }
+            ASSERT_TRUE(
+                    std::regex_match(std::string(info.operatorNumeric), kOperatorNumericRe));
         }
     }
 
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 5d514a0..00f4468 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -16,8 +16,39 @@
 
 #include <radio_hidl_hal_utils_v1_6.h>
 
+bool isServiceValidForDeviceConfiguration(hidl_string& serviceName) {
+    if (isSsSsEnabled()) {
+        // Device is configured as SSSS.
+        if (serviceName != RADIO_SERVICE_SLOT1_NAME) {
+            ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str());
+            return false;
+        }
+    } else if (isDsDsEnabled()) {
+        // Device is configured as DSDS.
+        if (serviceName != RADIO_SERVICE_SLOT1_NAME && serviceName != RADIO_SERVICE_SLOT2_NAME) {
+            ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str());
+            return false;
+        }
+    } else if (isTsTsEnabled()) {
+        // Device is configured as TSTS.
+        if (serviceName != RADIO_SERVICE_SLOT1_NAME && serviceName != RADIO_SERVICE_SLOT2_NAME &&
+            serviceName != RADIO_SERVICE_SLOT3_NAME) {
+            ALOGI("%s instance is not valid for TSTS device.", serviceName.c_str());
+            return false;
+        }
+    }
+    return true;
+}
+
 void RadioHidlTest_v1_6::SetUp() {
-    radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(GetParam());
+    hidl_string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(serviceName);
     ASSERT_NE(nullptr, radio_v1_6.get());
 
     radioRsp_v1_6 = new (std::nothrow) RadioResponse_v1_6(*this);
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 3185f98..54c2977 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -48,7 +48,9 @@
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
 
-#define RADIO_SERVICE_NAME "slot1"
+#define RADIO_SERVICE_SLOT1_NAME "slot1"  // HAL instance name for SIM slot 1 or single SIM device
+#define RADIO_SERVICE_SLOT2_NAME "slot2"  // HAL instance name for SIM slot 2 on dual SIM device
+#define RADIO_SERVICE_SLOT3_NAME "slot3"  // HAL instance name for SIM slot 3 on triple SIM device
 
 class RadioHidlTest_v1_6;
 extern ::android::hardware::radio::V1_5::CardStatus cardStatus;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl
index 59016f2..924f402 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl
@@ -48,7 +48,7 @@
     boolean boolValue; // Always true, if present.
     int integer;
     long longInteger;
-    long dateTime;
+    long dateTime; // In milliseconds from epoch
 
     byte[] blob;
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 8fbc91a..66f79ce 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -935,15 +935,15 @@
 
     /**
      * Tag::CERTIFICATE_NOT_BEFORE the beginning of the validity of the certificate in UNIX epoch
-     * time in seconds.  This value is used when generating attestation or self signed certificates.
-     * ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if this tag is not
-     * provided to generateKey or importKey.
+     * time in milliseconds.  This value is used when generating attestation or self signed
+     * certificates.  ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if
+     * this tag is not provided to generateKey or importKey.
      */
     CERTIFICATE_NOT_BEFORE = (6 << 28) /* TagType:DATE */ | 1008,
 
     /**
      * Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch time in
-     * seconds.  This value is used when generating attestation or self signed certificates.
+     * milliseconds.  This value is used when generating attestation or self signed certificates.
      * ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey or
      * importKey.
      */
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 4789204..8c4e0c3 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -59,6 +59,11 @@
 namespace test {
 
 namespace {
+
+// Overhead for PKCS#1 v1.5 signature padding of undigested messages.  Digested messages have
+// additional overhead, for the digest algorithmIdentifier required by PKCS#1.
+const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11;
+
 typedef KeyMintAidlTestBase::KeyData KeyData;
 // Predicate for testing basic characteristics validity in generation or import.
 bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel,
@@ -590,6 +595,205 @@
     VerifyMessage(key_blob_, message, signature, params);
 }
 
+void KeyMintAidlTestBase::LocalVerifyMessage(const string& message, const string& signature,
+                                             const AuthorizationSet& params) {
+    SCOPED_TRACE("LocalVerifyMessage");
+
+    // Retrieve the public key from the leaf certificate.
+    ASSERT_GT(cert_chain_.size(), 0);
+    X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    ASSERT_TRUE(key_cert.get());
+    EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
+    ASSERT_TRUE(pub_key.get());
+
+    Digest digest = params.GetTagValue(TAG_DIGEST).value();
+    PaddingMode padding = PaddingMode::NONE;
+    auto tag = params.GetTagValue(TAG_PADDING);
+    if (tag.has_value()) {
+        padding = tag.value();
+    }
+
+    if (digest == Digest::NONE) {
+        switch (EVP_PKEY_id(pub_key.get())) {
+            case EVP_PKEY_EC: {
+                vector<uint8_t> data((EVP_PKEY_bits(pub_key.get()) + 7) / 8);
+                size_t data_size = std::min(data.size(), message.size());
+                memcpy(data.data(), message.data(), data_size);
+                EC_KEY_Ptr ecdsa(EVP_PKEY_get1_EC_KEY(pub_key.get()));
+                ASSERT_TRUE(ecdsa.get());
+                ASSERT_EQ(1,
+                          ECDSA_verify(0, reinterpret_cast<const uint8_t*>(data.data()), data_size,
+                                       reinterpret_cast<const uint8_t*>(signature.data()),
+                                       signature.size(), ecdsa.get()));
+                break;
+            }
+            case EVP_PKEY_RSA: {
+                vector<uint8_t> data(EVP_PKEY_size(pub_key.get()));
+                size_t data_size = std::min(data.size(), message.size());
+                memcpy(data.data(), message.data(), data_size);
+
+                RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pub_key.get())));
+                ASSERT_TRUE(rsa.get());
+
+                size_t key_len = RSA_size(rsa.get());
+                int openssl_padding = RSA_NO_PADDING;
+                switch (padding) {
+                    case PaddingMode::NONE:
+                        ASSERT_TRUE(data_size <= key_len);
+                        ASSERT_EQ(key_len, signature.size());
+                        openssl_padding = RSA_NO_PADDING;
+                        break;
+                    case PaddingMode::RSA_PKCS1_1_5_SIGN:
+                        ASSERT_TRUE(data_size + kPkcs1UndigestedSignaturePaddingOverhead <=
+                                    key_len);
+                        openssl_padding = RSA_PKCS1_PADDING;
+                        break;
+                    default:
+                        ADD_FAILURE() << "Unsupported RSA padding mode " << padding;
+                }
+
+                vector<uint8_t> decrypted_data(key_len);
+                int bytes_decrypted = RSA_public_decrypt(
+                        signature.size(), reinterpret_cast<const uint8_t*>(signature.data()),
+                        decrypted_data.data(), rsa.get(), openssl_padding);
+                ASSERT_GE(bytes_decrypted, 0);
+
+                const uint8_t* compare_pos = decrypted_data.data();
+                size_t bytes_to_compare = bytes_decrypted;
+                uint8_t zero_check_result = 0;
+                if (padding == PaddingMode::NONE && data_size < bytes_to_compare) {
+                    // If the data is short, for "unpadded" signing we zero-pad to the left.  So
+                    // during verification we should have zeros on the left of the decrypted data.
+                    // Do a constant-time check.
+                    const uint8_t* zero_end = compare_pos + bytes_to_compare - data_size;
+                    while (compare_pos < zero_end) zero_check_result |= *compare_pos++;
+                    ASSERT_EQ(0, zero_check_result);
+                    bytes_to_compare = data_size;
+                }
+                ASSERT_EQ(0, memcmp(compare_pos, data.data(), bytes_to_compare));
+                break;
+            }
+            default:
+                ADD_FAILURE() << "Unknown public key type";
+        }
+    } else {
+        EVP_MD_CTX digest_ctx;
+        EVP_MD_CTX_init(&digest_ctx);
+        EVP_PKEY_CTX* pkey_ctx;
+        const EVP_MD* md = openssl_digest(digest);
+        ASSERT_NE(md, nullptr);
+        ASSERT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md, nullptr, pub_key.get()));
+
+        if (padding == PaddingMode::RSA_PSS) {
+            EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0);
+            EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0);
+        }
+
+        ASSERT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx,
+                                            reinterpret_cast<const uint8_t*>(message.data()),
+                                            message.size()));
+        ASSERT_EQ(1, EVP_DigestVerifyFinal(&digest_ctx,
+                                           reinterpret_cast<const uint8_t*>(signature.data()),
+                                           signature.size()));
+        EVP_MD_CTX_cleanup(&digest_ctx);
+    }
+}
+
+string KeyMintAidlTestBase::LocalRsaEncryptMessage(const string& message,
+                                                   const AuthorizationSet& params) {
+    SCOPED_TRACE("LocalRsaEncryptMessage");
+
+    // Retrieve the public key from the leaf certificate.
+    if (cert_chain_.empty()) {
+        ADD_FAILURE() << "No public key available";
+        return "Failure";
+    }
+    X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+    EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
+    RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pub_key.get())));
+
+    // Retrieve relevant tags.
+    Digest digest = Digest::NONE;
+    Digest mgf_digest = Digest::NONE;
+    PaddingMode padding = PaddingMode::NONE;
+
+    auto digest_tag = params.GetTagValue(TAG_DIGEST);
+    if (digest_tag.has_value()) digest = digest_tag.value();
+    auto pad_tag = params.GetTagValue(TAG_PADDING);
+    if (pad_tag.has_value()) padding = pad_tag.value();
+    auto mgf_tag = params.GetTagValue(TAG_RSA_OAEP_MGF_DIGEST);
+    if (mgf_tag.has_value()) mgf_digest = mgf_tag.value();
+
+    const EVP_MD* md = openssl_digest(digest);
+    const EVP_MD* mgf_md = openssl_digest(mgf_digest);
+
+    // Set up encryption context.
+    EVP_PKEY_CTX_Ptr ctx(EVP_PKEY_CTX_new(pub_key.get(), /* engine= */ nullptr));
+    if (EVP_PKEY_encrypt_init(ctx.get()) <= 0) {
+        ADD_FAILURE() << "Encryption init failed: " << ERR_peek_last_error();
+        return "Failure";
+    }
+
+    int rc = -1;
+    switch (padding) {
+        case PaddingMode::NONE:
+            rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING);
+            break;
+        case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+            rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING);
+            break;
+        case PaddingMode::RSA_OAEP:
+            rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING);
+            break;
+        default:
+            break;
+    }
+    if (rc <= 0) {
+        ADD_FAILURE() << "Set padding failed: " << ERR_peek_last_error();
+        return "Failure";
+    }
+    if (padding == PaddingMode::RSA_OAEP) {
+        if (!EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), md)) {
+            ADD_FAILURE() << "Set digest failed: " << ERR_peek_last_error();
+            return "Failure";
+        }
+        if (!EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), mgf_md)) {
+            ADD_FAILURE() << "Set MGF digest failed: " << ERR_peek_last_error();
+            return "Failure";
+        }
+    }
+
+    // Determine output size.
+    size_t outlen;
+    if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen,
+                         reinterpret_cast<const uint8_t*>(message.data()), message.size()) <= 0) {
+        ADD_FAILURE() << "Determine output size failed: " << ERR_peek_last_error();
+        return "Failure";
+    }
+
+    // Left-zero-pad the input if necessary.
+    const uint8_t* to_encrypt = reinterpret_cast<const uint8_t*>(message.data());
+    size_t to_encrypt_len = message.size();
+
+    std::unique_ptr<string> zero_padded_message;
+    if (padding == PaddingMode::NONE && to_encrypt_len < outlen) {
+        zero_padded_message.reset(new string(outlen, '\0'));
+        memcpy(zero_padded_message->data() + (outlen - to_encrypt_len), message.data(),
+               message.size());
+        to_encrypt = reinterpret_cast<const uint8_t*>(zero_padded_message->data());
+        to_encrypt_len = outlen;
+    }
+
+    // Do the encryption.
+    string output(outlen, '\0');
+    if (EVP_PKEY_encrypt(ctx.get(), reinterpret_cast<uint8_t*>(output.data()), &outlen, to_encrypt,
+                         to_encrypt_len) <= 0) {
+        ADD_FAILURE() << "Encryption failed: " << ERR_peek_last_error();
+        return "Failure";
+    }
+    return output;
+}
+
 string KeyMintAidlTestBase::EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
                                            const AuthorizationSet& in_params,
                                            AuthorizationSet* out_params) {
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index cb38938..d8f1bb3 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -162,7 +162,10 @@
                        const string& signature, const AuthorizationSet& params);
     void VerifyMessage(const string& message, const string& signature,
                        const AuthorizationSet& params);
+    void LocalVerifyMessage(const string& message, const string& signature,
+                            const AuthorizationSet& params);
 
+    string LocalRsaEncryptMessage(const string& message, const AuthorizationSet& params);
     string EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
                           const AuthorizationSet& in_params, AuthorizationSet* out_params);
     string EncryptMessage(const string& message, const AuthorizationSet& params,
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index cd7d603..293a010 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -482,7 +482,6 @@
     void CheckBaseParams(const vector<KeyCharacteristics>& keyCharacteristics) {
         AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
-        EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
 
         // Check that some unexpected tags/values are NOT present.
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT));
@@ -495,7 +494,6 @@
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
 
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
-        EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
     }
 
     AuthorizationSet CheckCommonParams(const vector<KeyCharacteristics>& keyCharacteristics) {
@@ -1986,6 +1984,50 @@
     string message = "12345678901234567890123456789012";
     string signature = SignMessage(
             message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
+    LocalVerifyMessage(message, signature,
+                       AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
+}
+
+/*
+ * SigningOperationsTest.RsaAllPaddingsAndDigests
+ *
+ * Verifies RSA signature/verification for all padding modes and digests.
+ */
+TEST_P(SigningOperationsTest, RsaAllPaddingsAndDigests) {
+    auto authorizations = AuthorizationSetBuilder()
+                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                  .RsaSigningKey(2048, 65537)
+                                  .Digest(ValidDigests(true /* withNone */, true /* withMD5 */))
+                                  .Padding(PaddingMode::NONE)
+                                  .Padding(PaddingMode::RSA_PSS)
+                                  .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+                                  .SetDefaultValidity();
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(authorizations));
+
+    string message(128, 'a');
+    string corrupt_message(message);
+    ++corrupt_message[corrupt_message.size() / 2];
+
+    for (auto padding :
+         {PaddingMode::NONE, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}) {
+        for (auto digest : ValidDigests(true /* withNone */, true /* withMD5 */)) {
+            if (padding == PaddingMode::NONE && digest != Digest::NONE) {
+                // Digesting only makes sense with padding.
+                continue;
+            }
+
+            if (padding == PaddingMode::RSA_PSS && digest == Digest::NONE) {
+                // PSS requires digesting.
+                continue;
+            }
+
+            string signature =
+                    SignMessage(message, AuthorizationSetBuilder().Digest(digest).Padding(padding));
+            LocalVerifyMessage(message, signature,
+                               AuthorizationSetBuilder().Digest(digest).Padding(padding));
+        }
+    }
 }
 
 /*
@@ -2432,6 +2474,39 @@
 }
 
 /*
+ * SigningOperationsTest.EcdsaAllDigestsAndCurves
+ *
+ * Verifies ECDSA signature/verification for all digests and curves.
+ */
+TEST_P(SigningOperationsTest, EcdsaAllDigestsAndCurves) {
+    auto digests = ValidDigests(true /* withNone */, false /* withMD5 */);
+
+    string message = "1234567890";
+    string corrupt_message = "2234567890";
+    for (auto curve : ValidCurves()) {
+        SCOPED_TRACE(testing::Message() << "Curve::" << curve);
+        ErrorCode error = GenerateKey(AuthorizationSetBuilder()
+                                              .Authorization(TAG_NO_AUTH_REQUIRED)
+                                              .EcdsaSigningKey(curve)
+                                              .Digest(digests)
+                                              .SetDefaultValidity());
+        EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate key for EC curve " << curve;
+        if (error != ErrorCode::OK) {
+            continue;
+        }
+
+        for (auto digest : digests) {
+            SCOPED_TRACE(testing::Message() << "Digest::" << digest);
+            string signature = SignMessage(message, AuthorizationSetBuilder().Digest(digest));
+            LocalVerifyMessage(message, signature, AuthorizationSetBuilder().Digest(digest));
+        }
+
+        auto rc = DeleteKey();
+        ASSERT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED);
+    }
+}
+
+/*
  * SigningOperationsTest.EcdsaAllCurves
  *
  * Verifies that ECDSA operations succeed with all possible curves.
@@ -2699,207 +2774,6 @@
 typedef KeyMintAidlTestBase VerificationOperationsTest;
 
 /*
- * VerificationOperationsTest.RsaSuccess
- *
- * Verifies that a simple RSA signature/verification sequence succeeds.
- */
-TEST_P(VerificationOperationsTest, RsaSuccess) {
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                 .RsaSigningKey(2048, 65537)
-                                                 .Digest(Digest::NONE)
-                                                 .Padding(PaddingMode::NONE)
-                                                 .SetDefaultValidity()));
-    string message = "12345678901234567890123456789012";
-    string signature = SignMessage(
-            message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
-    VerifyMessage(message, signature,
-                  AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
-}
-
-/*
- * VerificationOperationsTest.RsaAllPaddingsAndDigests
- *
- * Verifies RSA signature/verification for all padding modes and digests.
- */
-TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) {
-    auto authorizations = AuthorizationSetBuilder()
-                                  .Authorization(TAG_NO_AUTH_REQUIRED)
-                                  .RsaSigningKey(2048, 65537)
-                                  .Digest(ValidDigests(true /* withNone */, true /* withMD5 */))
-                                  .Padding(PaddingMode::NONE)
-                                  .Padding(PaddingMode::RSA_PSS)
-                                  .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
-                                  .SetDefaultValidity();
-
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(authorizations));
-
-    string message(128, 'a');
-    string corrupt_message(message);
-    ++corrupt_message[corrupt_message.size() / 2];
-
-    for (auto padding :
-         {PaddingMode::NONE, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}) {
-        for (auto digest : ValidDigests(true /* withNone */, true /* withMD5 */)) {
-            if (padding == PaddingMode::NONE && digest != Digest::NONE) {
-                // Digesting only makes sense with padding.
-                continue;
-            }
-
-            if (padding == PaddingMode::RSA_PSS && digest == Digest::NONE) {
-                // PSS requires digesting.
-                continue;
-            }
-
-            string signature =
-                    SignMessage(message, AuthorizationSetBuilder().Digest(digest).Padding(padding));
-            VerifyMessage(message, signature,
-                          AuthorizationSetBuilder().Digest(digest).Padding(padding));
-
-            /* TODO(seleneh) add exportkey tests back later when we have decided on
-             * the new api.
-                        if (digest != Digest::NONE) {
-                            // Verify with OpenSSL.
-                            vector<uint8_t> pubkey;
-                            ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &pubkey));
-
-                            const uint8_t* p = pubkey.data();
-                            EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr, &p, pubkey.size()));
-                            ASSERT_TRUE(pkey.get());
-
-                            EVP_MD_CTX digest_ctx;
-                            EVP_MD_CTX_init(&digest_ctx);
-                            EVP_PKEY_CTX* pkey_ctx;
-                            const EVP_MD* md = openssl_digest(digest);
-                            ASSERT_NE(md, nullptr);
-                            EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md,
-             nullptr, pkey.get()));
-
-                            switch (padding) {
-                                case PaddingMode::RSA_PSS:
-                                    EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx,
-               RSA_PKCS1_PSS_PADDING), 0); EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx,
-               EVP_MD_size(md)), 0); break; case PaddingMode::RSA_PKCS1_1_5_SIGN:
-                                    // PKCS1 is the default; don't need to set anything.
-                                    break;
-                                default:
-                                    FAIL();
-                                    break;
-                            }
-
-                            EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(),
-               message.size())); EXPECT_EQ(1, EVP_DigestVerifyFinal(&digest_ctx,
-                                                            reinterpret_cast<const
-               uint8_t*>(signature.data()), signature.size())); EVP_MD_CTX_cleanup(&digest_ctx);
-                        }
-            */
-
-            // Corrupt signature shouldn't verify.
-            string corrupt_signature(signature);
-            ++corrupt_signature[corrupt_signature.size() / 2];
-
-            EXPECT_EQ(ErrorCode::OK,
-                      Begin(KeyPurpose::VERIFY,
-                            AuthorizationSetBuilder().Digest(digest).Padding(padding)));
-            string result;
-            EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, corrupt_signature, &result));
-
-            // Corrupt message shouldn't verify
-            EXPECT_EQ(ErrorCode::OK,
-                      Begin(KeyPurpose::VERIFY,
-                            AuthorizationSetBuilder().Digest(digest).Padding(padding)));
-            EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corrupt_message, signature, &result));
-        }
-    }
-}
-
-/*
- * VerificationOperationsTest.RsaAllDigestsAndCurves
- *
- * Verifies ECDSA signature/verification for all digests and curves.
- */
-TEST_P(VerificationOperationsTest, EcdsaAllDigestsAndCurves) {
-    auto digests = ValidDigests(true /* withNone */, false /* withMD5 */);
-
-    string message = "1234567890";
-    string corrupt_message = "2234567890";
-    for (auto curve : ValidCurves()) {
-        ErrorCode error = GenerateKey(AuthorizationSetBuilder()
-                                              .Authorization(TAG_NO_AUTH_REQUIRED)
-                                              .EcdsaSigningKey(curve)
-                                              .Digest(digests)
-                                              .SetDefaultValidity());
-        EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate key for EC curve " << curve;
-        if (error != ErrorCode::OK) {
-            continue;
-        }
-
-        for (auto digest : digests) {
-            string signature = SignMessage(message, AuthorizationSetBuilder().Digest(digest));
-            VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(digest));
-
-            /* TODO(seleneh) add exportkey tests back later when we have decided on
-             * the new api.
-
-                        // Verify with OpenSSL
-                        if (digest != Digest::NONE) {
-                            vector<uint8_t> pubkey;
-                            ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &pubkey))
-                                    << curve << ' ' << digest;
-
-                            const uint8_t* p = pubkey.data();
-                            EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr, &p, pubkey.size()));
-                            ASSERT_TRUE(pkey.get());
-
-                            EVP_MD_CTX digest_ctx;
-                            EVP_MD_CTX_init(&digest_ctx);
-                            EVP_PKEY_CTX* pkey_ctx;
-                            const EVP_MD* md = openssl_digest(digest);
-
-                            EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md,
-             nullptr, pkey.get()))
-                                    << curve << ' ' << digest;
-
-                            EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(),
-               message.size()))
-                                    << curve << ' ' << digest;
-
-                            EXPECT_EQ(1,
-                                      EVP_DigestVerifyFinal(&digest_ctx,
-                                                            reinterpret_cast<const
-               uint8_t*>(signature.data()), signature.size()))
-                                    << curve << ' ' << digest;
-
-                            EVP_MD_CTX_cleanup(&digest_ctx);
-                        }
-            */
-            // Corrupt signature shouldn't verify.
-            string corrupt_signature(signature);
-            ++corrupt_signature[corrupt_signature.size() / 2];
-
-            EXPECT_EQ(ErrorCode::OK,
-                      Begin(KeyPurpose::VERIFY, AuthorizationSetBuilder().Digest(digest)))
-                    << curve << ' ' << digest;
-
-            string result;
-            EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, corrupt_signature, &result))
-                    << curve << ' ' << digest;
-
-            // Corrupt message shouldn't verify
-            EXPECT_EQ(ErrorCode::OK,
-                      Begin(KeyPurpose::VERIFY, AuthorizationSetBuilder().Digest(digest)))
-                    << curve << ' ' << digest;
-
-            EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corrupt_message, signature, &result))
-                    << curve << ' ' << digest;
-        }
-
-        auto rc = DeleteKey();
-        ASSERT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED);
-    }
-}
-
-/*
  * VerificationOperationsTest.HmacSigningKeyCannotVerify
  *
  * Verifies HMAC signing and verification, but that a signing key cannot be used to verify.
@@ -3016,7 +2890,7 @@
     string message(1024 / 8, 'a');
     auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS);
     string signature = SignMessage(message, params);
-    VerifyMessage(message, signature, params);
+    LocalVerifyMessage(message, signature, params);
 }
 
 /*
@@ -3058,7 +2932,7 @@
     string message(1024 / 8, 'a');
     auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS);
     string signature = SignMessage(message, params);
-    VerifyMessage(message, signature, params);
+    LocalVerifyMessage(message, signature, params);
 }
 
 /*
@@ -3116,7 +2990,7 @@
     string message(32, 'a');
     auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
     string signature = SignMessage(message, params);
-    VerifyMessage(message, signature, params);
+    LocalVerifyMessage(message, signature, params);
 }
 
 /*
@@ -3143,7 +3017,7 @@
     string message(32, 'a');
     auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
     string signature = SignMessage(message, params);
-    VerifyMessage(message, signature, params);
+    LocalVerifyMessage(message, signature, params);
 }
 
 /*
@@ -3169,7 +3043,7 @@
     string message(32, 'a');
     auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
     string signature = SignMessage(message, params);
-    VerifyMessage(message, signature, params);
+    LocalVerifyMessage(message, signature, params);
 }
 
 /*
@@ -3195,7 +3069,7 @@
     string message(32, 'a');
     auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256);
     string signature = SignMessage(message, params);
-    VerifyMessage(message, signature, params);
+    LocalVerifyMessage(message, signature, params);
 }
 
 /*
@@ -3329,7 +3203,7 @@
  */
 TEST_P(ImportKeyTest, TripleDesFailure) {
     string key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");
-    uint32_t bitlen = key.size() * 8;
+    uint32_t bitlen = key.size() * 7;
     for (uint32_t key_size : {bitlen - 1, bitlen + 1, bitlen - 8, bitlen + 8}) {
         // Explicit key size doesn't match that of the provided key.
         auto result = ImportKey(AuthorizationSetBuilder()
@@ -3343,19 +3217,19 @@
                 << "unexpected result: " << result;
     }
     // Explicit key size matches that of the provided key, but it's not a valid size.
-    string long_key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");
+    string long_key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f735800");
     ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
               ImportKey(AuthorizationSetBuilder()
                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                .TripleDesEncryptionKey(long_key.size() * 8)
+                                .TripleDesEncryptionKey(long_key.size() * 7)
                                 .EcbMode()
                                 .Padding(PaddingMode::PKCS7),
                         KeyFormat::RAW, long_key));
-    string short_key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");
+    string short_key = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f73");
     ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE,
               ImportKey(AuthorizationSetBuilder()
                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                .TripleDesEncryptionKey(short_key.size() * 8)
+                                .TripleDesEncryptionKey(short_key.size() * 7)
                                 .EcbMode()
                                 .Padding(PaddingMode::PKCS7),
                         KeyFormat::RAW, short_key));
@@ -3753,7 +3627,7 @@
 /*
  * EncryptionOperationsTest.RsaNoPaddingSuccess
  *
- * Verifies that raw RSA encryption works.
+ * Verifies that raw RSA decryption works.
  */
 TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) {
     for (uint64_t exponent : {3, 65537}) {
@@ -3765,10 +3639,10 @@
 
         string message = string(2048 / 8, 'a');
         auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
-        string ciphertext1 = EncryptMessage(message, params);
+        string ciphertext1 = LocalRsaEncryptMessage(message, params);
         EXPECT_EQ(2048U / 8, ciphertext1.size());
 
-        string ciphertext2 = EncryptMessage(message, params);
+        string ciphertext2 = LocalRsaEncryptMessage(message, params);
         EXPECT_EQ(2048U / 8, ciphertext2.size());
 
         // Unpadded RSA is deterministic
@@ -3781,7 +3655,7 @@
 /*
  * EncryptionOperationsTest.RsaNoPaddingShortMessage
  *
- * Verifies that raw RSA encryption of short messages works.
+ * Verifies that raw RSA decryption of short messages works.
  */
 TEST_P(EncryptionOperationsTest, RsaNoPaddingShortMessage) {
     ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -3793,76 +3667,47 @@
     string message = "1";
     auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
 
-    string ciphertext = EncryptMessage(message, params);
+    string ciphertext = LocalRsaEncryptMessage(message, params);
     EXPECT_EQ(2048U / 8, ciphertext.size());
 
     string expected_plaintext = string(2048U / 8 - 1, 0) + message;
     string plaintext = DecryptMessage(ciphertext, params);
 
     EXPECT_EQ(expected_plaintext, plaintext);
-
-    // Degenerate case, encrypting a numeric 1 yields 0x00..01 as the ciphertext.
-    message = static_cast<char>(1);
-    ciphertext = EncryptMessage(message, params);
-    EXPECT_EQ(2048U / 8, ciphertext.size());
-    EXPECT_EQ(ciphertext, string(2048U / 8 - 1, 0) + message);
 }
 
 /*
- * EncryptionOperationsTest.RsaNoPaddingTooLong
- *
- * Verifies that raw RSA encryption of too-long messages fails in the expected way.
- */
-TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLong) {
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                 .RsaEncryptionKey(2048, 65537)
-                                                 .Padding(PaddingMode::NONE)
-                                                 .SetDefaultValidity()));
-
-    string message(2048 / 8 + 1, 'a');
-
-    auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE);
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
-
-    string result;
-    EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result));
-}
-
-/*
- * EncryptionOperationsTest.RsaNoPaddingTooLarge
- *
- * Verifies that raw RSA encryption of too-large (numerically) messages fails in the expected
- * way.
- */
-// TODO(seleneh) add RsaNoPaddingTooLarge test back after decided and implemented new
-// version of ExportKey inside generateKey
-
-/*
  * EncryptionOperationsTest.RsaOaepSuccess
  *
- * Verifies that RSA-OAEP encryption operations work, with all digests.
+ * Verifies that RSA-OAEP decryption operations work, with all digests.
  */
 TEST_P(EncryptionOperationsTest, RsaOaepSuccess) {
     auto digests = ValidDigests(false /* withNone */, true /* withMD5 */);
 
     size_t key_size = 2048;  // Need largish key for SHA-512 test.
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                 .RsaEncryptionKey(key_size, 65537)
-                                                 .Padding(PaddingMode::RSA_OAEP)
-                                                 .Digest(digests)
-                                                 .SetDefaultValidity()));
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                  .RsaEncryptionKey(key_size, 65537)
+                                  .Padding(PaddingMode::RSA_OAEP)
+                                  .Digest(digests)
+                                  .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA1)
+                                  .SetDefaultValidity()));
 
     string message = "Hello";
 
     for (auto digest : digests) {
-        auto params = AuthorizationSetBuilder().Digest(digest).Padding(PaddingMode::RSA_OAEP);
-        string ciphertext1 = EncryptMessage(message, params);
+        SCOPED_TRACE(testing::Message() << "digest-" << digest);
+
+        auto params = AuthorizationSetBuilder()
+                              .Digest(digest)
+                              .Padding(PaddingMode::RSA_OAEP)
+                              .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA1);
+        string ciphertext1 = LocalRsaEncryptMessage(message, params);
         if (HasNonfatalFailure()) std::cout << "-->" << digest << std::endl;
         EXPECT_EQ(key_size / 8, ciphertext1.size());
 
-        string ciphertext2 = EncryptMessage(message, params);
+        string ciphertext2 = LocalRsaEncryptMessage(message, params);
         EXPECT_EQ(key_size / 8, ciphertext2.size());
 
         // OAEP randomizes padding so every result should be different (with astronomically high
@@ -3892,7 +3737,7 @@
 /*
  * EncryptionOperationsTest.RsaOaepInvalidDigest
  *
- * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
+ * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate
  * without a digest.
  */
 TEST_P(EncryptionOperationsTest, RsaOaepInvalidDigest) {
@@ -3904,13 +3749,13 @@
                                                  .SetDefaultValidity()));
 
     auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_OAEP).Digest(Digest::NONE);
-    EXPECT_EQ(ErrorCode::INCOMPATIBLE_DIGEST, Begin(KeyPurpose::ENCRYPT, params));
+    EXPECT_EQ(ErrorCode::INCOMPATIBLE_DIGEST, Begin(KeyPurpose::DECRYPT, params));
 }
 
 /*
  * EncryptionOperationsTest.RsaOaepInvalidPadding
  *
- * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
+ * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate
  * with a padding value that is only suitable for signing/verifying.
  */
 TEST_P(EncryptionOperationsTest, RsaOaepInvalidPadding) {
@@ -3922,13 +3767,13 @@
                                                  .SetDefaultValidity()));
 
     auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PSS).Digest(Digest::NONE);
-    EXPECT_EQ(ErrorCode::UNSUPPORTED_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params));
+    EXPECT_EQ(ErrorCode::UNSUPPORTED_PADDING_MODE, Begin(KeyPurpose::DECRYPT, params));
 }
 
 /*
  * EncryptionOperationsTest.RsaOaepDecryptWithWrongDigest
  *
- * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to decrypt
+ * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to decrypt
  * with a different digest than was used to encrypt.
  */
 TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) {
@@ -3941,7 +3786,7 @@
                                                  .Digest(Digest::SHA_2_224, Digest::SHA_2_256)
                                                  .SetDefaultValidity()));
     string message = "Hello World!";
-    string ciphertext = EncryptMessage(
+    string ciphertext = LocalRsaEncryptMessage(
             message,
             AuthorizationSetBuilder().Digest(Digest::SHA_2_224).Padding(PaddingMode::RSA_OAEP));
 
@@ -3954,34 +3799,9 @@
 }
 
 /*
- * EncryptionOperationsTest.RsaOaepTooLarge
- *
- * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to encrypt a
- * too-large message.
- */
-TEST_P(EncryptionOperationsTest, RsaOaepTooLarge) {
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                 .RsaEncryptionKey(2048, 65537)
-                                                 .Padding(PaddingMode::RSA_OAEP)
-                                                 .Digest(Digest::SHA_2_256)
-                                                 .SetDefaultValidity()));
-    constexpr size_t digest_size = 256 /* SHA_2_256 */ / 8;
-    constexpr size_t oaep_overhead = 2 * digest_size + 2;
-    string message(2048 / 8 - oaep_overhead + 1, 'a');
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, AuthorizationSetBuilder()
-                                                                .Padding(PaddingMode::RSA_OAEP)
-                                                                .Digest(Digest::SHA_2_256)));
-    string result;
-    ErrorCode error = Finish(message, &result);
-    EXPECT_TRUE(error == ErrorCode::INVALID_INPUT_LENGTH || error == ErrorCode::INVALID_ARGUMENT);
-    EXPECT_EQ(0U, result.size());
-}
-
-/*
  * EncryptionOperationsTest.RsaOaepWithMGFDigestSuccess
  *
- * Verifies that RSA-OAEP encryption operations work, with all SHA 256 digests and all type of MGF1
+ * Verifies that RSA-OAEP decryption operations work, with all SHA 256 digests and all type of MGF1
  * digests.
  */
 TEST_P(EncryptionOperationsTest, RsaOaepWithMGFDigestSuccess) {
@@ -4003,11 +3823,11 @@
                               .Authorization(TAG_RSA_OAEP_MGF_DIGEST, digest)
                               .Digest(Digest::SHA_2_256)
                               .Padding(PaddingMode::RSA_OAEP);
-        string ciphertext1 = EncryptMessage(message, params);
+        string ciphertext1 = LocalRsaEncryptMessage(message, params);
         if (HasNonfatalFailure()) std::cout << "-->" << digest << std::endl;
         EXPECT_EQ(key_size / 8, ciphertext1.size());
 
-        string ciphertext2 = EncryptMessage(message, params);
+        string ciphertext2 = LocalRsaEncryptMessage(message, params);
         EXPECT_EQ(key_size / 8, ciphertext2.size());
 
         // OAEP randomizes padding so every result should be different (with astronomically high
@@ -4037,7 +3857,7 @@
 /*
  * EncryptionOperationsTest.RsaOaepWithMGFIncompatibleDigest
  *
- * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate
+ * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate
  * with incompatible MGF digest.
  */
 TEST_P(EncryptionOperationsTest, RsaOaepWithMGFIncompatibleDigest) {
@@ -4055,7 +3875,7 @@
                           .Padding(PaddingMode::RSA_OAEP)
                           .Digest(Digest::SHA_2_256)
                           .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_224);
-    EXPECT_EQ(ErrorCode::INCOMPATIBLE_MGF_DIGEST, Begin(KeyPurpose::ENCRYPT, params));
+    EXPECT_EQ(ErrorCode::INCOMPATIBLE_MGF_DIGEST, Begin(KeyPurpose::DECRYPT, params));
 }
 
 /*
@@ -4079,7 +3899,7 @@
                           .Padding(PaddingMode::RSA_OAEP)
                           .Digest(Digest::SHA_2_256)
                           .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::NONE);
-    EXPECT_EQ(ErrorCode::UNSUPPORTED_MGF_DIGEST, Begin(KeyPurpose::ENCRYPT, params));
+    EXPECT_EQ(ErrorCode::UNSUPPORTED_MGF_DIGEST, Begin(KeyPurpose::DECRYPT, params));
 }
 
 /*
@@ -4096,10 +3916,10 @@
 
     string message = "Hello World!";
     auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
-    string ciphertext1 = EncryptMessage(message, params);
+    string ciphertext1 = LocalRsaEncryptMessage(message, params);
     EXPECT_EQ(2048U / 8, ciphertext1.size());
 
-    string ciphertext2 = EncryptMessage(message, params);
+    string ciphertext2 = LocalRsaEncryptMessage(message, params);
     EXPECT_EQ(2048U / 8, ciphertext2.size());
 
     // PKCS1 v1.5 randomizes padding so every result should be different.
@@ -4123,27 +3943,6 @@
 }
 
 /*
- * EncryptionOperationsTest.RsaPkcs1TooLarge
- *
- * Verifies that RSA PKCS encryption fails in the correct way when the message is too large.
- */
-TEST_P(EncryptionOperationsTest, RsaPkcs1TooLarge) {
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
-                                                 .RsaEncryptionKey(2048, 65537)
-                                                 .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
-                                                 .SetDefaultValidity()));
-    string message(2048 / 8 - 10, 'a');
-
-    auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
-    string result;
-    ErrorCode error = Finish(message, &result);
-    EXPECT_TRUE(error == ErrorCode::INVALID_INPUT_LENGTH || error == ErrorCode::INVALID_ARGUMENT);
-    EXPECT_EQ(0U, result.size());
-}
-
-/*
  * EncryptionOperationsTest.EcdsaEncrypt
  *
  * Verifies that attempting to use ECDSA keys to encrypt fails in the correct way.
diff --git a/sensors/1.0/ISensors.hal b/sensors/1.0/ISensors.hal
index 8d41de2..0e172ef 100644
--- a/sensors/1.0/ISensors.hal
+++ b/sensors/1.0/ISensors.hal
@@ -103,7 +103,7 @@
      * Flush adds a FLUSH_COMPLETE metadata event to the end of the "batch mode"
      * FIFO for the specified sensor and flushes the FIFO.  If the FIFO is empty
      * or if the sensor doesn't support batching (FIFO size zero), return
-     * SUCCESS and add a trivial FLUSH_COMPLETE event added to the event stream.
+     * OK and add a trivial FLUSH_COMPLETE event added to the event stream.
      * This applies to all sensors other than one-shot sensors. If the sensor
      * is a one-shot sensor, flush must return BAD_VALUE and not generate any
      * flush complete metadata.  If the sensor is not active at the time flush()
diff --git a/sensors/1.0/types.hal b/sensors/1.0/types.hal
index cbbe92f..ac7be06 100644
--- a/sensors/1.0/types.hal
+++ b/sensors/1.0/types.hal
@@ -1130,7 +1130,7 @@
 
     /**
      * High performance mode hint. Device is able to use up more power and take
-     * more reources to improve throughput and latency in high performance mode.
+     * more resources to improve throughput and latency in high performance mode.
      * One possible use case is virtual reality, when sensor latency need to be
      * carefully controlled.
      * int32_t: 1 or 0, denote if device is in/out of high performance mode,
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 56bc9cf..1f579ba 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -190,7 +190,7 @@
     });
 }
 
-// Test if sensor list returned is valid
+// Test if sensor hal can switch to different operation modes
 TEST_P(SensorsHidlTest, SetOperationMode) {
     std::vector<SensorInfo> sensorList = getSensorsList();
 
@@ -208,7 +208,7 @@
     ASSERT_EQ(Result::OK, S()->setOperationMode(OperationMode::NORMAL));
 }
 
-// Test if sensor list returned is valid
+// Test if sensor hal can receive injected events in loopback mode
 TEST_P(SensorsHidlTest, InjectSensorEventData) {
     std::vector<SensorInfo> sensorList = getSensorsList();
     std::vector<SensorInfo> sensorSupportInjection;
diff --git a/tv/tuner/1.0/vts/functional/AndroidTest.xml b/tv/tuner/1.0/vts/functional/AndroidTest.xml
index 3a2db27..18c2b59 100644
--- a/tv/tuner/1.0/vts/functional/AndroidTest.xml
+++ b/tv/tuner/1.0/vts/functional/AndroidTest.xml
@@ -30,5 +30,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalTvTunerV1_0TargetTest" />
+        <option name="native-test-timeout" value="30m" />
     </test>
 </configuration>
diff --git a/tv/tuner/1.1/vts/functional/AndroidTest.xml b/tv/tuner/1.1/vts/functional/AndroidTest.xml
index 28f95db..3e6878c 100644
--- a/tv/tuner/1.1/vts/functional/AndroidTest.xml
+++ b/tv/tuner/1.1/vts/functional/AndroidTest.xml
@@ -29,5 +29,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalTvTunerV1_1TargetTest" />
+        <option name="native-test-timeout" value="30m" />
     </test>
 </configuration>
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp
index 3bcf32a..4dff853 100644
--- a/tv/tuner/1.1/vts/functional/FilterTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp
@@ -306,8 +306,12 @@
             android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
     if (filter_v1_1 != NULL) {
         status = filter_v1_1->configureMonitorEvent(monitorEventTypes);
-        mFilterCallbacks[filterId]->testFilterScramblingEvent();
-        mFilterCallbacks[filterId]->testFilterIpCidEvent();
+        if (monitorEventTypes & DemuxFilterMonitorEventType::SCRAMBLING_STATUS) {
+            mFilterCallbacks[filterId]->testFilterScramblingEvent();
+        }
+        if (monitorEventTypes & DemuxFilterMonitorEventType::IP_CID_CHANGE) {
+            mFilterCallbacks[filterId]->testFilterIpCidEvent();
+        }
     } else {
         ALOGW("[vts] Can't cast IFilter into v1_1.");
         return failure();
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h
index 59611fa..72c8129 100644
--- a/tv/tuner/1.1/vts/functional/FilterTests.h
+++ b/tv/tuner/1.1/vts/functional/FilterTests.h
@@ -57,6 +57,7 @@
 using android::hardware::tv::tuner::V1_1::AvStreamType;
 using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt;
 using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent;
+using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType;
 using android::hardware::tv::tuner::V1_1::IFilterCallback;
 using android::hardware::tv::tuner::V1_1::ITuner;
 
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index e70c320..1a9def8 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -112,8 +112,8 @@
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
                                                filterConf.config1_0.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
-    ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId));
     ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId));
+    ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId));
     ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId));
     ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_0.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
index 0688219..d049b07 100644
--- a/tv/tuner/config/TunerTestingConfigReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
@@ -52,6 +52,7 @@
 using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
 using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
 using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode;
 using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
 using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
 using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
@@ -593,6 +594,16 @@
         }
         dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(dvbt->getBandwidth());
         dvbtSettings.isHighPriority = dvbt->getIsHighPriority();
+        dvbtSettings.hierarchy = static_cast<FrontendDvbtHierarchy>(dvbt->getHierarchy());
+        dvbtSettings.hpCoderate = static_cast<FrontendDvbtCoderate>(dvbt->getHpCoderate());
+        dvbtSettings.lpCoderate = static_cast<FrontendDvbtCoderate>(dvbt->getLpCoderate());
+        dvbtSettings.guardInterval =
+                static_cast<FrontendDvbtGuardInterval>(dvbt->getGuardInterval());
+        dvbtSettings.standard = static_cast<FrontendDvbtStandard>(dvbt->getStandard());
+        dvbtSettings.isMiso = dvbt->getIsMiso();
+        dvbtSettings.plpMode = static_cast<FrontendDvbtPlpMode>(dvbt->getPlpMode());
+        dvbtSettings.plpId = dvbt->getPlpId();
+        dvbtSettings.plpGroupId = dvbt->getPlpGroupId();
         if (dvbt->hasConstellation()) {
             dvbtSettings.constellation =
                     static_cast<FrontendDvbtConstellation>(dvbt->getConstellation());
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index ef73315..d026bf9 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -180,11 +180,29 @@
     ctor public DvbtFrontendSettings();
     method @Nullable public java.math.BigInteger getBandwidth();
     method @Nullable public java.math.BigInteger getConstellation();
+    method @Nullable public java.math.BigInteger getGuardInterval();
+    method @Nullable public java.math.BigInteger getHierarchy();
+    method @Nullable public java.math.BigInteger getHpCoderate();
     method @Nullable public java.math.BigInteger getIsHighPriority();
+    method @Nullable public java.math.BigInteger getIsMiso();
+    method @Nullable public java.math.BigInteger getLpCoderate();
+    method @Nullable public java.math.BigInteger getPlpGroupId();
+    method @Nullable public java.math.BigInteger getPlpId();
+    method @Nullable public java.math.BigInteger getPlpMode();
+    method @Nullable public java.math.BigInteger getStandard();
     method @Nullable public java.math.BigInteger getTransmissionMode();
     method public void setBandwidth(@Nullable java.math.BigInteger);
     method public void setConstellation(@Nullable java.math.BigInteger);
+    method public void setGuardInterval(@Nullable java.math.BigInteger);
+    method public void setHierarchy(@Nullable java.math.BigInteger);
+    method public void setHpCoderate(@Nullable java.math.BigInteger);
     method public void setIsHighPriority(@Nullable java.math.BigInteger);
+    method public void setIsMiso(@Nullable java.math.BigInteger);
+    method public void setLpCoderate(@Nullable java.math.BigInteger);
+    method public void setPlpGroupId(@Nullable java.math.BigInteger);
+    method public void setPlpId(@Nullable java.math.BigInteger);
+    method public void setPlpMode(@Nullable java.math.BigInteger);
+    method public void setStandard(@Nullable java.math.BigInteger);
     method public void setTransmissionMode(@Nullable java.math.BigInteger);
   }
 
diff --git a/tv/tuner/config/sample_tuner_vts_config_1_0.xml b/tv/tuner/config/sample_tuner_vts_config_1_0.xml
index 2624076..347e984 100644
--- a/tv/tuner/config/sample_tuner_vts_config_1_0.xml
+++ b/tv/tuner/config/sample_tuner_vts_config_1_0.xml
@@ -54,7 +54,10 @@
         <frontends>
             <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
                       connectToCicamId="0" frequency="578000" endFrequency="800000">
-                <dvbtFrontendSettings bandwidth="8" transmissionMode="1" isHighPriority="1"/>
+                <dvbtFrontendSettings bandwidth="8" transmissionMode="1" isHighPriority="1"
+                                      constellation="1" hierarchy="1" hpCoderate="1" lpCoderate="1"
+                                      guardInterval="1" standard="1" isMiso="0" plpMode="1"
+                                      plpId="0" plpGroupId="0"/>
             </frontend>
             <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
                       connectToCicamId="0" frequency="578000" endFrequency="800000">
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 5216837..6a04b7e 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -61,9 +61,18 @@
 
     <xs:complexType name="dvbtFrontendSettings">
         <xs:attribute name="bandwidth" type="xs:nonNegativeInteger" use="required"/>
-        <xs:attribute name="transmissionMode" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="constellation" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="guardInterval" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="hierarchy" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="hpCoderate" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="lpCoderate" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="isHighPriority" type="xs:nonNegativeInteger" use="required"/>
-        <xs:attribute name="constellation" type="xs:nonNegativeInteger" use="optional"/>
+        <xs:attribute name="isMiso" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="plpGroupId" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="plpId" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="plpMode" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="standard" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="transmissionMode" type="xs:nonNegativeInteger" use="required"/>
     </xs:complexType>
     <xs:complexType name="dvbsFrontendSettings">
         <xs:attribute name="inputStreamId" type="xs:nonNegativeInteger" use="required"/>