Merge changes from topic 'nnapi_hal_move' into oc-mr1-dev

* changes:
  Initial VTS tests for Neural Networks HAL.
  Move neuralnetworks HAL to hardware/interfaces
diff --git a/audio/2.0/config/audio_policy_configuration.xsd b/audio/2.0/config/audio_policy_configuration.xsd
index 48b9a9b..c94da80 100644
--- a/audio/2.0/config/audio_policy_configuration.xsd
+++ b/audio/2.0/config/audio_policy_configuration.xsd
@@ -188,6 +188,7 @@
                 <xs:complexType>
                     <xs:sequence>
                         <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
                     </xs:sequence>
                     <xs:attribute name="name" type="xs:token" use="required"/>
                     <xs:attribute name="role" type="role" use="required"/>
@@ -199,6 +200,10 @@
                     <xs:field xpath="samplingRate"/>
                     <xs:field xpath="channelMasks"/>
                 </xs:unique>
+                <xs:unique name="mixPortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
             </xs:element>
         </xs:sequence>
     </xs:complexType>
@@ -365,16 +370,42 @@
         <xs:attribute name="samplingRates" type="samplingRates" use="required"/>
         <xs:attribute name="channelMasks" type="channelMask" use="required"/>
     </xs:complexType>
+    <xs:simpleType name="gainMode">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_GAIN_MODE_JOINT"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_CHANNELS"/>
+            <xs:enumeration value="AUDIO_GAIN_MODE_RAMP"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="gains">
+        <xs:sequence>
+            <xs:element name="gain" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:token" use="required"/>
+                    <xs:attribute name="mode" type="gainMode" use="required"/>
+                    <xs:attribute name="channel_mask" type="channelMask" use="optional"/>
+                    <xs:attribute name="minValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="defaultValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="stepValueMB" type="xs:int" use="optional"/>
+                    <xs:attribute name="minRampMs" type="xs:int" use="optional"/>
+                    <xs:attribute name="maxRampMs" type="xs:int" use="optional"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
     <xs:complexType name="devicePorts">
         <xs:sequence>
             <xs:element name="devicePort" minOccurs="0" maxOccurs="unbounded">
                 <xs:complexType>
                     <xs:sequence>
                         <xs:element name="profile" type="profile" minOccurs="0" maxOccurs="unbounded"/>
+                        <xs:element name="gains" type="gains" minOccurs="0"/>
                     </xs:sequence>
                     <xs:attribute name="tagName" type="xs:token" use="required"/>
                     <xs:attribute name="type" type="audioDevice" use="required"/>
                     <xs:attribute name="role" type="role" use="required"/>
+                    <xs:attribute name="address" type="xs:string" use="optional"/>
                 </xs:complexType>
                 <xs:unique name="devicePortProfileUniqueness">
                     <xs:selector xpath="profile"/>
@@ -382,6 +413,10 @@
                     <xs:field xpath="samplingRate"/>
                     <xs:field xpath="channelMasks"/>
                 </xs:unique>
+                <xs:unique name="devicePortGainUniqueness">
+                    <xs:selector xpath="gains/gain"/>
+                    <xs:field xpath="@name"/>
+                </xs:unique>
             </xs:element>
         </xs:sequence>
     </xs:complexType>
diff --git a/automotive/vehicle/2.1/Android.mk b/automotive/vehicle/2.1/Android.mk
index 2dfbefc..3001da0 100644
--- a/automotive/vehicle/2.1/Android.mk
+++ b/automotive/vehicle/2.1/Android.mk
@@ -208,6 +208,25 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (VmsAvailabilityStateIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsAvailabilityStateIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsAvailabilityStateIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (VmsBaseMessageIntegerValuesIndex)
 #
 GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsBaseMessageIntegerValuesIndex.java
@@ -227,25 +246,6 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VmsDataMessageIntegerValuesIndex)
-#
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsDataMessageIntegerValuesIndex.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsDataMessageIntegerValuesIndex
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
 # Build types.hal (VmsMessageType)
 #
 GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageType.java
@@ -265,6 +265,44 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (VmsMessageWithLayerAndPublisherIdIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsMessageWithLayerAndPublisherIdIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (VmsMessageWithLayerIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageWithLayerIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsMessageWithLayerIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (VmsOfferingMessageIntegerValuesIndex)
 #
 GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsOfferingMessageIntegerValuesIndex.java
@@ -284,9 +322,9 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VmsSimpleMessageIntegerValuesIndex)
+# Build types.hal (VmsSubscriptionsStateIntegerValuesIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSimpleMessageIntegerValuesIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSubscriptionsStateIntegerValuesIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -296,26 +334,7 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsSimpleMessageIntegerValuesIndex
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (VmsSubscriptionResponseFormat)
-#
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSubscriptionResponseFormat.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsSubscriptionResponseFormat
+        android.hardware.automotive.vehicle@2.1::types.VmsSubscriptionsStateIntegerValuesIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
@@ -548,6 +567,25 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (VmsAvailabilityStateIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsAvailabilityStateIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsAvailabilityStateIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (VmsBaseMessageIntegerValuesIndex)
 #
 GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsBaseMessageIntegerValuesIndex.java
@@ -567,25 +605,6 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VmsDataMessageIntegerValuesIndex)
-#
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsDataMessageIntegerValuesIndex.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsDataMessageIntegerValuesIndex
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
 # Build types.hal (VmsMessageType)
 #
 GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageType.java
@@ -605,6 +624,44 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
+# Build types.hal (VmsMessageWithLayerAndPublisherIdIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsMessageWithLayerAndPublisherIdIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (VmsMessageWithLayerIntegerValuesIndex)
+#
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsMessageWithLayerIntegerValuesIndex.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.automotive.vehicle@2.1::types.VmsMessageWithLayerIntegerValuesIndex
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (VmsOfferingMessageIntegerValuesIndex)
 #
 GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsOfferingMessageIntegerValuesIndex.java
@@ -624,9 +681,9 @@
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (VmsSimpleMessageIntegerValuesIndex)
+# Build types.hal (VmsSubscriptionsStateIntegerValuesIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSimpleMessageIntegerValuesIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSubscriptionsStateIntegerValuesIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -636,26 +693,7 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsSimpleMessageIntegerValuesIndex
-
-$(GEN): $(LOCAL_PATH)/types.hal
-	$(transform-generated-source)
-LOCAL_GENERATED_SOURCES += $(GEN)
-
-#
-# Build types.hal (VmsSubscriptionResponseFormat)
-#
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/VmsSubscriptionResponseFormat.java
-$(GEN): $(HIDL)
-$(GEN): PRIVATE_HIDL := $(HIDL)
-$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
-$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
-$(GEN): PRIVATE_CUSTOM_TOOL = \
-        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
-        -Ljava \
-        -randroid.hardware:hardware/interfaces \
-        -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.VmsSubscriptionResponseFormat
+        android.hardware.automotive.vehicle@2.1::types.VmsSubscriptionsStateIntegerValuesIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
diff --git a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h b/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h
index d024a55..701317b 100644
--- a/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h
+++ b/automotive/vehicle/2.1/default/impl/vhal_v2_1/DefaultConfig.h
@@ -86,7 +86,8 @@
     {
         .prop = OBD2_FREEZE_FRAME_CLEAR,
         .access = V2_0::VehiclePropertyAccess::WRITE,
-        .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE
+        .changeMode = V2_0::VehiclePropertyChangeMode::ON_CHANGE,
+        .configArray = {1}
     },
 
     {
diff --git a/automotive/vehicle/2.1/types.hal b/automotive/vehicle/2.1/types.hal
index e5f9411..53feb23 100644
--- a/automotive/vehicle/2.1/types.hal
+++ b/automotive/vehicle/2.1/types.hal
@@ -119,6 +119,8 @@
      * bytes is a serialized VMS message as defined in the vms protocol
      * which is opaque to the framework;
      *
+     * IVehicle#get must always return StatusCode::NOT_AVAILABLE.
+     *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ_WRITE
      */
@@ -131,33 +133,40 @@
     /**
      * OBD2 Live Sensor Data
      *
-     * This property uses COMPLEX data to send a snapshot of the current (live)
-     * values of the OBD2 sensors provided by the vehicle.
+     * Reports a snapshot of the current (live) values of the OBD2 sensors available.
      *
-     * VehiclePropConfig
-     *   configArray[0] : number of vendor-specific integer-valued sensors
-     *                    that can be returned in a frame.
-     *   configArray[1] : number of vendor-specific float-valued sensors
-     *                    that can be returned in a frame.
+     * The configArray is set as follows:
+     *   configArray[0] = number of vendor-specific integer-valued sensors
+     *   configArray[1] = number of vendor-specific float-valued sensors
      *
-     * The values are to be interpreted as follows:
-     * the indices defined in Obd2IntegerSensorIndex are to be used to
-     * read from int32Values;
-     * the indices defined in Obd2FloatSensorIndex are to be used to
-     * read from floatValues.
-     * the elements of bytes are to be interpreted as a bitmask, such that
-     * the bits 0 thru the integer value of
-     * Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[0]
-     * are 1 if the corresponding index is a valid sensor index whose value can
-     * be read in the returned int32Values vector, 0 otherwise.
-     * the bits Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX+1 thru
-     * Obd2FloatingSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[1]
-     * are 1 if the corresponding index is a valid sensor index whose value
-     * can be read in the returned floatValues vector, 0 otherwise.
+     * The values of this property are to be interpreted as in the following example.
+     * Considering a configArray = {2,3}
+     * int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2
+     * elements (that is, 33 elements);
+     * floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3
+     * elements (that is, 73 elements);
      *
-     * For example, int32Values[0] corresponds to FUEL_SYSTEM_STATUS, and
-     * floatValues[0] corresponds to CALCULATED_ENGINE_LOAD, but that mapping
-     * is only valid if the corresponding bits in the bytes vector are set to 1.
+     * It is possible for each frame to contain a different subset of sensor values, both system
+     * provided sensors, and vendor-specific ones. In order to support that, the bytes element
+     * of the property value is used as a bitmask,.
+     *
+     * bytes must have a sufficient number of bytes to represent the total number of possible
+     * sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as
+     * a contiguous bitmask such that each bit indicates the presence or absence of a sensor
+     * from the frame, starting with as many bits as the size of int32Values, immediately
+     * followed by as many bits as the size of floatValues.
+     *
+     * For example, should bytes[0] = 0x4C (0b01001100) it would mean that:
+     *   int32Values[0 and 1] are not valid sensor values
+     *   int32Values[2 and 3] are valid sensor values
+     *   int32Values[4 and 5] are not valid sensor values
+     *   int32Values[6] is a valid sensor value
+     *   int32Values[7] is not a valid sensor value
+     * Should bytes[5] = 0x61 (0b01100001) it would mean that:
+     *   int32Values[32] is a valid sensor value
+     *   floatValues[0 thru 3] are not valid sensor values
+     *   floatValues[4 and 5] are valid sensor values
+     *   floatValues[6] is not a valid sensor value
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -171,41 +180,23 @@
     /**
      * OBD2 Freeze Frame Sensor Data
      *
-     * This property uses COMPLEX data to send a snapshot of the values of the
-     * OBD2 sensors provided by the vehicle at the time that a diagnostic
-     * troubleshooting code (DTC) was recorded by the vehicle.
+     * Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
+     * occurred and was detected.
      *
-     * VehiclePropConfig
-     *   configArray[0] : number of vendor-specific integer-valued sensors
-     *                    that can be returned in a frame.
-     *   configArray[1] : number of vendor-specific float-valued sensors
-     *                    that can be returned in a frame.
+     * A configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.
      *
-     * A get of this property must take the following form:
-     *   int64Values[0]: timestamp of the freeze frame to retrieve.
-     *                   Valid timestamps are given by OBD2_DTC_INFO.
+     * The values of this property are to be interpreted in a similar fashion as those for
+     * OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty
+     * diagnostic troubleshooting code (DTC).
      *
-     * The values are to be interpreted as follows:
-     * the indices defined in Obd2IntegerSensorIndex are to be used to
-     * read from int32Values;
-     * the indices defined in Obd2FloatSensorIndex are to be used to
-     * read from floatValues;
-     * the elements of bytes are to be interpreted as a bitmask, such that
-     * the bits 0 thru the integer value of
-     * Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[0]
-     * are 1 if the corresponding index is a valid sensor index whose value can
-     * be read in the returned int32Values vector, 0 otherwise.
-     * the bits Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX+1 thru
-     * Obd2FloatingSensorIndex.LAST_SYSTEM_INDEX + the value of configArray[1]
-     * are 1 if the corresponding index is a valid sensor index whose value
-     * can be read in the returned floatValues vector, 0 otherwise.
-     * stringValue is the DTC that caused this freeze frame to be recorded.
+     * A IVehicle#get request of this property must provide a value for int64Values[0].
+     * This will be interpreted as the timestamp of the freeze frame to retrieve. A list of
+     * timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.
      *
-     * For example, int32Values[0] corresponds to FUEL_SYSTEM_STATUS, and
-     * floatValues[0] corresponds to CALCULATED_ENGINE_LOAD, but that mapping
-     * is only valid if the corresponding bits in the bytes vector are set to 1,
-     * and a possible valid stringValue is "P0176" to indicate a malfunction
-     * of the fuel composition sensor circuit.
+     * Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
+     * must be returned by the implementation. Because vehicles may have limited storage for
+     * freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if
+     * the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -223,7 +214,7 @@
      * memory and available for retrieval via OBD2_FREEZE_FRAME.
      *
      * The values are to be interpreted as follows:
-     * each element of int64Values is the timestamp at which a a fault code
+     * each element of int64Values must be the timestamp at which a a fault code
      * has been detected and the corresponding freeze frame stored, and each
      * such element can be used as the key to OBD2_FREEZE_FRAME to retrieve
      * the corresponding freeze frame.
@@ -241,14 +232,18 @@
      * OBD2 Freeze Frame Clear
      *
      * This property allows deletion of any of the freeze frames stored in
-     * vehicle memory, as described by OBD2_DTC_INFO.
+     * vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
      *
-     * A set of this property is to be interpreted as follows:
-     * if int64Values contains no elements, then all DTCs stored will be cleared;
-     * if int64Values contains one or more elements, then DTCs at the timestamps
-     * stored in int64Values will be cleared, and the others not cleared, except
-     * the memory will be compacted so that all remaining DTCs are stored
-     * contiguously.
+     * The configArray is set as follows:
+     *  configArray[0] = 1 if the implementation is able to clear individual freeze frames
+     *                   by timestamp, 0 otherwise
+     *
+     * IVehicle#set of this property is to be interpreted as follows:
+     *   if int64Values contains no elements, then all frames stored must be cleared;
+     *   if int64Values contains one or more elements, then frames at the timestamps
+     *   stored in int64Values must be cleared, and the others not cleared. Should the
+     *   vehicle not support selective clearing of freeze frames, this latter mode must
+     *   return NOT_AVAILABLE.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:WRITE
@@ -509,102 +504,196 @@
 };
 
 /**
- * This enum lists the types of supported VMS messages.
+ * This enum lists the types of supported VMS messages. It is used as the first
+ * integer in the vehicle property integers array and determines how the rest of
+ * the message is decoded.
  */
 enum VmsMessageType : int32_t {
-  /** A client subscribes to a layer. */
+  /**
+   * A request from the subscribers to the VMS service to subscribe to a layer.
+   *
+   * This message type uses enum VmsMessageWithLayerIntegerValuesIndex.
+   */
   SUBSCRIBE = 1,
 
-  /** A client unsubscribes from a layer. */
-  UNSUBSCRIBE = 2,
+  /**
+   * A request from the subscribers to the VMS service to subscribe to a layer from a specific publisher.
+   *
+   * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
+   */
+  SUBSCRIBE_TO_PUBLISHER = 2,
 
-  /** A client publishes a data packet. */
-  DATA = 3,
+  /**
+   * A request from the subscribers to the VMS service to unsubscribes from a layer.
+   *
+   * This message type uses enum VmsMessageWithLayerIntegerValuesIndex.
+   */
+  UNSUBSCRIBE = 3,
 
-  /** A client declaring layers offering. */
-  OFFERING = 4,
+  /**
+   * A request from the subscribers to the VMS service to unsubscribes from a layer from a specific publisher.
+   *
+   * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
+   */
+  UNSUBSCRIBE_TO_PUBLISHER = 4,
 
-  /** Requesting the list of available layers. */
-  AVAILABILITY_REQUEST = 5,
+  /**
+   * Information from the publishers to the VMS service about the layers which the client can publish.
+   *
+   * This message type uses enum VmsOfferingMessageIntegerValuesIndex.
+   */
+  OFFERING = 5,
 
-  /** Returning the list of available layers. */
-  AVAILABILITY_RESPONSE = 6,
+  /**
+   * A request from the subscribers to the VMS service to get the available layers.
+   *
+   * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+   */
+  AVAILABILITY_REQUEST = 6,
 
-  /** Sending to the HAL the current list of the available layers. */
-  AVAILABILITY_CHANGE = 7,
+  /**
+   * A request from the publishers to the VMS service to get the layers with subscribers.
+   *
+   * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+   */
+  SUBSCRIPTIONS_REQUEST = 7,
 
-  /** Requesting layers that have subscribers. */
-  SUBSCRIPTIONS_REQUEST = 8,
+  /**
+   * A response from the VMS service to the subscribers to a VmsMessageType.AVAILABILITY_REQUEST
+   *
+   * This message type uses enum VmsAvailabilityStateIntegerValuesIndex.
+   */
+  AVAILABILITY_RESPONSE = 8,
 
-  /** Returning layers that have subscribers. */
-  SUBSCRIPTIONS_RESPONSE = 9,
+  /**
+   * A notification from the VMS service to the subscribers on a change in the available layers.
+   *
+   * This message type uses enum VmsAvailabilityStateIntegerValuesIndex.
+   */
+  AVAILABILITY_CHANGE = 9,
 
-  /** Sending to the HAL the current list of the subscribed layers. */
-  SUBSCRIPTIONS_CHANGE = 10,
+  /**
+   * A response from the VMS service to the publishers to a VmsMessageType.SUBSCRIPTIONS_REQUEST
+   *
+   * This message type uses enum VmsSubscriptionsStateIntegerValuesIndex.
+   */
+  SUBSCRIPTIONS_RESPONSE = 10,
+
+  /**
+   * A notification from the VMS service to the publishers on a change in the layers with subscribers.
+   *
+   * This message type uses enum VmsSubscriptionsStateIntegerValuesIndex.
+   */
+  SUBSCRIPTIONS_CHANGE = 11,
+
+  /**
+   * A message from the VMS service to the subscribers or from the publishers to the VMS service
+   * with a serialized VMS data packet as defined in the VMS protocol.
+   *
+   * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+   */
+  DATA = 12,
 };
 
 /**
- * This enum provides the canonical mapping for VMS properties that have an
- * integer value.
+ * Every VMS message starts with the type of the message from the VmsMessageType enum.
+ * Messages with no parameters such as VmsMessageType.AVAILABILITY_REQUEST,
+ * VmsMessageType.SUBSCRIPTIONS_REQUEST and VmsMessageType.DATA are also based on this enum.
  */
 enum VmsBaseMessageIntegerValuesIndex : int32_t {
   /* The message type as enumerated by VmsMessageType enum. */
-  VMS_MESSAGE_TYPE = 0,
+  MESSAGE_TYPE = 0,
 };
 
 /*
- * This enum provides the canonical mapping for VMS SUBMIT and UNSUBMIT
- * messages integer value properties.
+ * A VMS message with a layer is sent as part of a VmsMessageType.SUBSCRIBE or
+ * VmsMessageType.UNSUBSCRIBE messages.
+ *
+ * The layer type is defined in the VMS protocol, and the subtype and version are
+ * controlled by the implementer of the publisher.
  */
-enum VmsSimpleMessageIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
-  /* The layer ID as defined in the vms protocol. */
-  VMS_LAYER_ID = 1,
+enum VmsMessageWithLayerIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
+  LAYER_TYPE = 1,
 
-  /* The version of the VMS layer. */
-  VMS_LAYER_VERSION = 2,
+  LAYER_SUBTYPE = 2,
 
-  /* The layer type as defined in the vms protocol */
-  VMS_LAYER_SUB_TYPE = 3,
+  LAYER_VERSION = 3,
 };
 
 /*
- * This enum provides the canonical mapping for VMS DATA
- * message integer value properties.
+ * A VMS message with a layer and publisher ID is sent as part of a
+ * VmsMessageType.SUBSCRIBE_TO_PUBLISHER and VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER messages.
  */
-enum VmsDataMessageIntegerValuesIndex : VmsSimpleMessageIntegerValuesIndex {
-  /* A publisher ID of the client that published this message. */
-  VMS_PUBLISHER_ID = 4,
+enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex : VmsMessageWithLayerIntegerValuesIndex {
+  PUBLISHER_ID = 4,
 };
 
 /*
- * This enum provides the canonical mapping for VMS offering messages integer
- * value properties
+ * An offering can be sent by publishers as part of VmsMessageType.OFFERING in order to
+ * advertise which layers they can publish and under which constraints: e.g., I can publish Layer X
+ * if someone else will publish Layer Y.
+ * The offering contains the publisher ID which was assigned to the publisher by the VMS service.
+ * A single offering is represented as:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * - Number of dependencies (N)
+ * - N x (Layer type, Layer subtype, Layer version)
  */
 enum VmsOfferingMessageIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
-  /* The ID assigend to the publisher by the VMS core. */
   PUBLISHER_ID = 1,
 
-  /* The number of VMS layer dependencies. */
-  VMS_NUMBER_OF_LAYERS_DEPENDENCIES = 2,
+  NUMBER_OF_OFFERS = 2,
 
-  /* The first index that contain dependencies */
-  FIRST_DEPENDENCIES_INDEX = 3,
+  OFFERING_START = 3,
 };
 
 /**
- * A VMS subscription request only contains its message type. The format of a VMS subscription
- * response is described below.
+ * A subscriptions state is sent to the publishers in response to a change in the subscriptions
+ * as part of a VmsMessageType.SUBSCRIPTIONS_CHANGE, or in response to a
+ * VmsMessageType.SUBSCRIPTIONS_REQUEST message as part of VmsMessageType.SUBSCRIPTIONS_RESPONSE.
+ * The VMS service issues monotonically increasing sequence numbers, and in case a subscriber receives
+ * a smaller sequnce number it should ignore the message.
+ * The subscriptions are sent as a list of layers followed by a list of associated layers:
+ * {Sequence number, N, M, N x layer, M x associated layer}
+ * A subscribed layer is represented as three integers:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * A subscribed associated layer is a layer with a list of publisher IDs. It is represented as:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * - Number of publisher IDs (N)
+ * - N x publisher ID
  */
-enum VmsSubscriptionResponseFormat : VmsBaseMessageIntegerValuesIndex {
-  /**
-    * Recipients should ignore any packet with a sequence number that is less than the highest
-    * sequence number they have seen thus far.
-    */
+enum VmsSubscriptionsStateIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
   SEQUENCE_NUMBER = 1,
 
-  /** The number of VMS layers. Each layer has two integers: type and version. */
   NUMBER_OF_LAYERS = 2,
 
-  /** The first index that contains a layer. */
-  FIRST_LAYER = 3,
+  NUMBER_OF_ASSOCIATED_LAYERS = 3,
+
+  SUBSCRIPTIONS_START = 4,
+};
+
+/**
+ * An availability state is sent to the subscribers in response to a change in the available
+ * layers as part of a VmsMessageType.AVAILABILITY_CHANGE message, or in response to a
+ * VmsMessageType.AVAILABILITY_REQUEST message as part of a VmsMessageType.AVAILABILITY_RESPONSE.
+ * The VMS service issues monotonically increasing sequence numbers, and in case a subscriber receives
+ * a smaller sequnce number, it should ignore the message.
+ * An available associated layer is a layer with a list of publisher IDs:
+ * - Layer type
+ * - Layer subtype
+ * - Layer version
+ * - Number of publisher IDs (N)
+ * - N x publisher ID
+*/
+enum VmsAvailabilityStateIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
+  SEQUENCE_NUMBER = 1,
+
+  NUMBER_OF_ASSOCIATED_LAYERS = 2,
+
+  LAYERS_START = 3,
 };
diff --git a/broadcastradio/1.0/types.hal b/broadcastradio/1.0/types.hal
index e9ac4b7..8c3ec11 100644
--- a/broadcastradio/1.0/types.hal
+++ b/broadcastradio/1.0/types.hal
@@ -212,12 +212,23 @@
     uint32_t     channel;   /** current channel. (e.g kHz for band type AM_FM) */
     uint32_t     subChannel; /** current sub channel. (FM_HD) */
 
-    /** Tuned to a program (not a noise). It's the same condition that would stop scan operation. */
+    /**
+     * Tuned to a program (not a noise). It's the same condition that would
+     * stop scan operation.
+     */
     bool         tuned;
 
     bool         stereo;    /** program is stereo or not */
     bool         digital;   /** digital program or not (e.g HD Radio program) */
-    uint32_t     signalStrength; /** signal strength from 0 to 100 */
-    vec<MetaData> metadata; /** non empty if meta data are present (e.g PTY, song title ...) */
+
+    /**
+     * Signal quality measured in 0% to 100% range.
+     *
+     * Despite the name, this is not a signal strength.
+     * The purpose of this field is primarily informative.
+     */
+    uint32_t signalStrength;
+
+    vec<MetaData> metadata; /** Metadata: PTY, song title etc. */
 };
 
diff --git a/broadcastradio/1.1/ITuner.hal b/broadcastradio/1.1/ITuner.hal
index a5c569a..cc2e58d 100644
--- a/broadcastradio/1.1/ITuner.hal
+++ b/broadcastradio/1.1/ITuner.hal
@@ -84,6 +84,13 @@
      * subsequent calls to startBackgroundScan, issuing a single
      * backgroundScanComplete callback.
      *
+     * If a device supports continuous background scanning, it may succeed
+     * (return OK and call backgroundScanComplete) without any additional
+     * operation performed.
+     *
+     * Foreground scanning may be implemented in the front end app with
+     * @1.0::ITuner scan operation.
+     *
      * @return result OK if the scan was properly scheduled (this does not mean
      *                it successfully finished).
      *                UNAVAILABLE if the background scan is unavailable,
diff --git a/broadcastradio/1.1/default/BroadcastRadio.cpp b/broadcastradio/1.1/default/BroadcastRadio.cpp
index 7916407..17ec780 100644
--- a/broadcastradio/1.1/default/BroadcastRadio.cpp
+++ b/broadcastradio/1.1/default/BroadcastRadio.cpp
@@ -143,7 +143,7 @@
         mTuner = nullptr;
     }
 
-    sp<Tuner> newTuner = new Tuner(callback);
+    sp<Tuner> newTuner = new Tuner(mClassId, callback);
     mTuner = newTuner;
     if (mClassId == Class::AM_FM) {
         auto ret = newTuner->setConfiguration(config);
diff --git a/broadcastradio/1.1/default/Tuner.cpp b/broadcastradio/1.1/default/Tuner.cpp
index 2985d42..f48a8db 100644
--- a/broadcastradio/1.1/default/Tuner.cpp
+++ b/broadcastradio/1.1/default/Tuner.cpp
@@ -33,7 +33,9 @@
 
 using V1_0::Band;
 using V1_0::BandConfig;
+using V1_0::Class;
 using V1_0::Direction;
+using utils::HalRevision;
 
 using std::chrono::milliseconds;
 using std::lock_guard;
@@ -49,14 +51,12 @@
     milliseconds tune = 150ms;
 } gDefaultDelay;
 
-Tuner::Tuner(const sp<V1_0::ITunerCallback>& callback)
-    : mCallback(callback),
+Tuner::Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& callback)
+    : mClassId(classId),
+      mCallback(callback),
       mCallback1_1(ITunerCallback::castFrom(callback).withDefault(nullptr)),
-      mVirtualFm(make_fm_radio()),
-      mIsAnalogForced(false) {
-    // TODO (b/36864090): inject this data in a more elegant way
-    setCompatibilityLevel(mCallback1_1 == nullptr ? 1 : 2);
-}
+      mVirtualRadio(getRadio(classId)),
+      mIsAnalogForced(false) {}
 
 void Tuner::forceClose() {
     lock_guard<mutex> lk(mMut);
@@ -66,6 +66,12 @@
 
 Return<Result> Tuner::setConfiguration(const BandConfig& config) {
     ALOGV("%s", __func__);
+    lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
+    if (mClassId != Class::AM_FM) {
+        ALOGE("Can't set AM/FM configuration on SAT/DT radio tuner");
+        return Result::INVALID_STATE;
+    }
 
     if (config.lowerLimit >= config.upperLimit) return Result::INVALID_ARGUMENTS;
 
@@ -77,6 +83,12 @@
         mAmfmConfig.antennaConnected = true;
         mCurrentProgram = utils::make_selector(mAmfmConfig.type, mAmfmConfig.lowerLimit);
 
+        if (mAmfmConfig.type == Band::FM_HD || mAmfmConfig.type == Band::FM) {
+            mVirtualRadio = std::ref(getFmRadio());
+        } else {
+            mVirtualRadio = std::ref(getAmRadio());
+        }
+
         mIsAmfmConfigSet = true;
         mCallback->configChange(Result::OK, mAmfmConfig);
     };
@@ -87,14 +99,14 @@
 
 Return<void> Tuner::getConfiguration(getConfiguration_cb _hidl_cb) {
     ALOGV("%s", __func__);
-
     lock_guard<mutex> lk(mMut);
-    if (mIsAmfmConfigSet) {
+
+    if (!mIsClosed && mIsAmfmConfigSet) {
         _hidl_cb(Result::OK, mAmfmConfig);
     } else {
         _hidl_cb(Result::NOT_INITIALIZED, {});
     }
-    return Void();
+    return {};
 }
 
 // makes ProgramInfo that points to no program
@@ -109,21 +121,19 @@
     return info11;
 }
 
-bool Tuner::isFmLocked() {
-    if (!utils::isAmFm(utils::getType(mCurrentProgram))) return false;
-    return mAmfmConfig.type == Band::FM_HD || mAmfmConfig.type == Band::FM;
+HalRevision Tuner::getHalRev() const {
+    if (mCallback1_1 != nullptr) {
+        return HalRevision::V1_1;
+    } else {
+        return HalRevision::V1_0;
+    }
 }
 
 void Tuner::tuneInternalLocked(const ProgramSelector& sel) {
-    VirtualRadio* virtualRadio = nullptr;
-    if (isFmLocked()) {
-        virtualRadio = &mVirtualFm;
-    }
-
     VirtualProgram virtualProgram;
-    if (virtualRadio != nullptr && virtualRadio->getProgram(sel, virtualProgram)) {
+    if (mVirtualRadio.get().getProgram(sel, virtualProgram)) {
         mCurrentProgram = virtualProgram.selector;
-        mCurrentProgramInfo = static_cast<ProgramInfo>(virtualProgram);
+        mCurrentProgramInfo = virtualProgram.getProgramInfo(getHalRev());
     } else {
         mCurrentProgram = sel;
         mCurrentProgramInfo = makeDummyProgramInfo(sel);
@@ -140,11 +150,9 @@
 Return<Result> Tuner::scan(Direction direction, bool skipSubChannel __unused) {
     ALOGV("%s", __func__);
     lock_guard<mutex> lk(mMut);
-    vector<VirtualProgram> list;
+    if (mIsClosed) return Result::NOT_INITIALIZED;
 
-    if (isFmLocked()) {
-        list = mVirtualFm.getProgramList();
-    }
+    auto list = mVirtualRadio.get().getProgramList();
 
     if (list.empty()) {
         mIsTuneCompleted = false;
@@ -196,9 +204,10 @@
 
 Return<Result> Tuner::step(Direction direction, bool skipSubChannel) {
     ALOGV("%s", __func__);
-    ALOGW_IF(!skipSubChannel, "can't step to next frequency without ignoring subChannel");
-
     lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
+
+    ALOGW_IF(!skipSubChannel, "can't step to next frequency without ignoring subChannel");
 
     if (!utils::isAmFm(utils::getType(mCurrentProgram))) {
         ALOGE("Can't step in anything else than AM/FM");
@@ -244,8 +253,8 @@
 
 Return<Result> Tuner::tune_1_1(const ProgramSelector& sel) {
     ALOGV("%s(%s)", __func__, toString(sel).c_str());
-
     lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
 
     if (utils::isAmFm(utils::getType(mCurrentProgram))) {
         ALOGW_IF(!mIsAmfmConfigSet, "AM/FM config not set");
@@ -269,12 +278,18 @@
 
 Return<Result> Tuner::cancel() {
     ALOGV("%s", __func__);
+    lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
+
     mThread.cancelAll();
     return Result::OK;
 }
 
 Return<Result> Tuner::cancelAnnouncement() {
     ALOGV("%s", __func__);
+    lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
+
     return Result::OK;
 }
 
@@ -287,46 +302,57 @@
 
 Return<void> Tuner::getProgramInformation_1_1(getProgramInformation_1_1_cb _hidl_cb) {
     ALOGV("%s", __func__);
-
     lock_guard<mutex> lk(mMut);
-    if (mIsTuneCompleted) {
+
+    if (mIsClosed) {
+        _hidl_cb(Result::NOT_INITIALIZED, {});
+    } else if (mIsTuneCompleted) {
         _hidl_cb(Result::OK, mCurrentProgramInfo);
     } else {
         _hidl_cb(Result::NOT_INITIALIZED, makeDummyProgramInfo(mCurrentProgram));
     }
-    return Void();
+    return {};
 }
 
 Return<ProgramListResult> Tuner::startBackgroundScan() {
     ALOGV("%s", __func__);
+    lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return ProgramListResult::NOT_INITIALIZED;
+
     return ProgramListResult::UNAVAILABLE;
 }
 
-Return<void> Tuner::getProgramList(const hidl_string& filter __unused, getProgramList_cb _hidl_cb) {
-    ALOGV("%s", __func__);
+Return<void> Tuner::getProgramList(const hidl_string& filter, getProgramList_cb _hidl_cb) {
+    ALOGV("%s(%s)", __func__, filter.c_str());
     lock_guard<mutex> lk(mMut);
-
-    auto& virtualRadio = mVirtualFm;
-    if (!isFmLocked()) {
-        ALOGI("bands other than FM are not supported yet");
-        _hidl_cb(ProgramListResult::OK, {});
-        return Void();
+    if (mIsClosed) {
+        _hidl_cb(ProgramListResult::NOT_INITIALIZED, {});
+        return {};
     }
 
-    auto list = virtualRadio.getProgramList();
+    auto list = mVirtualRadio.get().getProgramList();
     ALOGD("returning a list of %zu programs", list.size());
-    _hidl_cb(ProgramListResult::OK, vector<ProgramInfo>(list.begin(), list.end()));
-    return Void();
+    _hidl_cb(ProgramListResult::OK, getProgramInfoVector(list, getHalRev()));
+    return {};
 }
 
 Return<void> Tuner::isAnalogForced(isAnalogForced_cb _hidl_cb) {
     ALOGV("%s", __func__);
-    _hidl_cb(Result::OK, mIsAnalogForced);
-    return Void();
+    lock_guard<mutex> lk(mMut);
+
+    if (mIsClosed) {
+        _hidl_cb(Result::NOT_INITIALIZED, false);
+    } else {
+        _hidl_cb(Result::OK, mIsAnalogForced);
+    }
+    return {};
 }
 
 Return<Result> Tuner::setAnalogForced(bool isForced) {
     ALOGV("%s", __func__);
+    lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
+
     mIsAnalogForced = isForced;
     return Result::OK;
 }
diff --git a/broadcastradio/1.1/default/Tuner.h b/broadcastradio/1.1/default/Tuner.h
index 3efbd09..c4efe6e 100644
--- a/broadcastradio/1.1/default/Tuner.h
+++ b/broadcastradio/1.1/default/Tuner.h
@@ -29,7 +29,7 @@
 namespace implementation {
 
 struct Tuner : public ITuner {
-    Tuner(const sp<V1_0::ITunerCallback>& callback);
+    Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& callback);
 
     void forceClose();
 
@@ -53,13 +53,13 @@
    private:
     std::mutex mMut;
     WorkerThread mThread;
-    bool mIsClosed = false;  // TODO(b/36864090): use it
+    bool mIsClosed = false;
 
+    V1_0::Class mClassId;
     const sp<V1_0::ITunerCallback> mCallback;
     const sp<V1_1::ITunerCallback> mCallback1_1;
 
-    VirtualRadio mVirtualFm;
-
+    std::reference_wrapper<VirtualRadio> mVirtualRadio;
     bool mIsAmfmConfigSet = false;
     V1_0::BandConfig mAmfmConfig;
     bool mIsTuneCompleted = false;
@@ -67,8 +67,8 @@
     ProgramInfo mCurrentProgramInfo = {};
     std::atomic<bool> mIsAnalogForced;
 
+    utils::HalRevision getHalRev() const;
     void tuneInternalLocked(const ProgramSelector& sel);
-    bool isFmLocked();  // TODO(b/36864090): make it generic, not FM only
 };
 
 }  // namespace implementation
diff --git a/broadcastradio/1.1/default/VirtualProgram.cpp b/broadcastradio/1.1/default/VirtualProgram.cpp
index 4c6b3b1..1c2285d 100644
--- a/broadcastradio/1.1/default/VirtualProgram.cpp
+++ b/broadcastradio/1.1/default/VirtualProgram.cpp
@@ -25,28 +25,24 @@
 namespace V1_1 {
 namespace implementation {
 
+using std::vector;
+
 using V1_0::MetaData;
 using V1_0::MetadataKey;
 using V1_0::MetadataType;
+using utils::HalRevision;
 
-// TODO (b/36864090): inject this data in a more elegant way
-static int gHalVersion = 2;  // 1 = 1.0, 2 = 1.1
-
-void setCompatibilityLevel(int halversion) {
-    gHalVersion = halversion;
-}
-
-static MetaData createDemoBitmap(MetadataKey key) {
+static MetaData createDemoBitmap(MetadataKey key, HalRevision halRev) {
     MetaData bmp = {MetadataType::INT, key, resources::demoPngId, {}, {}, {}};
-    if (gHalVersion < 2) {
+    if (halRev < HalRevision::V1_1) {
         bmp.type = MetadataType::RAW;
         bmp.intValue = 0;
-        bmp.rawValue = std::vector<uint8_t>(resources::demoPng, std::end(resources::demoPng));
+        bmp.rawValue = hidl_vec<uint8_t>(resources::demoPng, std::end(resources::demoPng));
     }
     return bmp;
 }
 
-VirtualProgram::operator ProgramInfo() const {
+ProgramInfo VirtualProgram::getProgramInfo(HalRevision halRev) const {
     ProgramInfo info11 = {};
     auto& info10 = info11.base;
 
@@ -61,8 +57,8 @@
         {MetadataType::TEXT, MetadataKey::RDS_PS, {}, {}, programName, {}},
         {MetadataType::TEXT, MetadataKey::TITLE, {}, {}, songTitle, {}},
         {MetadataType::TEXT, MetadataKey::ARTIST, {}, {}, songArtist, {}},
-        createDemoBitmap(MetadataKey::ICON),
-        createDemoBitmap(MetadataKey::ART),
+        createDemoBitmap(MetadataKey::ICON, halRev),
+        createDemoBitmap(MetadataKey::ART, halRev),
     });
 
     return info11;
@@ -89,6 +85,15 @@
     return false;
 }
 
+vector<ProgramInfo> getProgramInfoVector(const vector<VirtualProgram>& vec, HalRevision halRev) {
+    vector<ProgramInfo> out;
+    out.reserve(vec.size());
+    for (auto&& program : vec) {
+        out.push_back(program.getProgramInfo(halRev));
+    }
+    return out;
+}
+
 }  // namespace implementation
 }  // namespace V1_1
 }  // namespace broadcastradio
diff --git a/broadcastradio/1.1/default/VirtualProgram.h b/broadcastradio/1.1/default/VirtualProgram.h
index 2ee21a7..a14830d 100644
--- a/broadcastradio/1.1/default/VirtualProgram.h
+++ b/broadcastradio/1.1/default/VirtualProgram.h
@@ -17,7 +17,7 @@
 #define ANDROID_HARDWARE_BROADCASTRADIO_V1_1_VIRTUALPROGRAM_H
 
 #include <android/hardware/broadcastradio/1.1/types.h>
-#include <cstdint>
+#include <broadcastradio-utils/Utils.h>
 
 namespace android {
 namespace hardware {
@@ -25,9 +25,12 @@
 namespace V1_1 {
 namespace implementation {
 
-// TODO (b/36864090): inject this data in a more elegant way
-void setCompatibilityLevel(int halversion);
-
+/**
+ * A radio program mock.
+ *
+ * This represents broadcast waves flying over the air,
+ * not an entry for a captured station in the radio tuner memory.
+ */
 struct VirtualProgram {
     ProgramSelector selector;
 
@@ -35,10 +38,14 @@
     std::string songArtist = "";
     std::string songTitle = "";
 
-    explicit operator ProgramInfo() const;
+    ProgramInfo getProgramInfo(utils::HalRevision halRev) const;
+
     friend bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs);
 };
 
+std::vector<ProgramInfo> getProgramInfoVector(const std::vector<VirtualProgram>& vec,
+                                              utils::HalRevision halRev);
+
 }  // namespace implementation
 }  // namespace V1_1
 }  // namespace broadcastradio
diff --git a/broadcastradio/1.1/default/VirtualRadio.cpp b/broadcastradio/1.1/default/VirtualRadio.cpp
index 692e7bc..36d47a9 100644
--- a/broadcastradio/1.1/default/VirtualRadio.cpp
+++ b/broadcastradio/1.1/default/VirtualRadio.cpp
@@ -13,9 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "BroadcastRadioDefault.VirtualRadio"
+//#define LOG_NDEBUG 0
+
 #include "VirtualRadio.h"
 
 #include <broadcastradio-utils/Utils.h>
+#include <log/log.h>
 
 namespace android {
 namespace hardware {
@@ -24,6 +28,7 @@
 namespace implementation {
 
 using V1_0::Band;
+using V1_0::Class;
 
 using std::lock_guard;
 using std::move;
@@ -32,7 +37,7 @@
 
 using utils::make_selector;
 
-const vector<VirtualProgram> gInitialFmPrograms{
+static const vector<VirtualProgram> gInitialFmPrograms{
     {make_selector(Band::FM, 94900), "Wild 94.9", "Drake ft. Rihanna", "Too Good"},
     {make_selector(Band::FM, 96500), "KOIT", "Celine Dion", "All By Myself"},
     {make_selector(Band::FM, 97300), "Alice@97.3", "Drops of Jupiter", "Train"},
@@ -42,7 +47,8 @@
     {make_selector(Band::FM, 106100), "106 KMEL", "Drake", "Marvins Room"},
 };
 
-VirtualRadio::VirtualRadio(VirtualRadio&& o) : mPrograms(move(o.mPrograms)) {}
+static VirtualRadio gEmptyRadio({});
+static VirtualRadio gFmRadio(gInitialFmPrograms);
 
 VirtualRadio::VirtualRadio(const vector<VirtualProgram> initialList) : mPrograms(initialList) {}
 
@@ -62,8 +68,34 @@
     return false;
 }
 
-VirtualRadio make_fm_radio() {
-    return VirtualRadio(gInitialFmPrograms);
+VirtualRadio& getRadio(V1_0::Class classId) {
+    switch (classId) {
+        case Class::AM_FM:
+            return getFmRadio();
+        case Class::SAT:
+            return getSatRadio();
+        case Class::DT:
+            return getDigitalRadio();
+        default:
+            ALOGE("Invalid class ID");
+            return gEmptyRadio;
+    }
+}
+
+VirtualRadio& getAmRadio() {
+    return gEmptyRadio;
+}
+
+VirtualRadio& getFmRadio() {
+    return gFmRadio;
+}
+
+VirtualRadio& getSatRadio() {
+    return gEmptyRadio;
+}
+
+VirtualRadio& getDigitalRadio() {
+    return gEmptyRadio;
 }
 
 }  // namespace implementation
diff --git a/broadcastradio/1.1/default/VirtualRadio.h b/broadcastradio/1.1/default/VirtualRadio.h
index 4cdc72f..3c7ae5c 100644
--- a/broadcastradio/1.1/default/VirtualRadio.h
+++ b/broadcastradio/1.1/default/VirtualRadio.h
@@ -27,9 +27,16 @@
 namespace V1_1 {
 namespace implementation {
 
+/**
+ * A radio frequency space mock.
+ *
+ * This represents all broadcast waves in the air for a given radio technology,
+ * not a captured station list in the radio tuner memory.
+ *
+ * It's meant to abstract out radio content from default tuner implementation.
+ */
 class VirtualRadio {
    public:
-    VirtualRadio(VirtualRadio&& o);
     VirtualRadio(const std::vector<VirtualProgram> initialList);
 
     std::vector<VirtualProgram> getProgramList();
@@ -40,7 +47,29 @@
     std::vector<VirtualProgram> mPrograms;
 };
 
-VirtualRadio make_fm_radio();
+/**
+ * Get virtual radio space for a given radio class.
+ *
+ * As a space, each virtual radio always exists. For example, DAB frequencies
+ * exists in US, but contains no programs.
+ *
+ * The lifetime of the virtual radio space is virtually infinite, but for the
+ * needs of default implementation, it's bound with the lifetime of default
+ * implementation process.
+ *
+ * Internally, it's a static object, so trying to access the reference during
+ * default implementation library unloading may result in segmentation fault.
+ * It's unlikely for testing purposes.
+ *
+ * @param classId A class of radio technology.
+ * @return A reference to virtual radio space for a given technology.
+ */
+VirtualRadio& getRadio(V1_0::Class classId);
+
+VirtualRadio& getAmRadio();
+VirtualRadio& getFmRadio();
+VirtualRadio& getSatRadio();
+VirtualRadio& getDigitalRadio();
 
 }  // namespace implementation
 }  // namespace V1_1
diff --git a/broadcastradio/1.1/utils/Utils.cpp b/broadcastradio/1.1/utils/Utils.cpp
index 8bb7691..50a407c 100644
--- a/broadcastradio/1.1/utils/Utils.cpp
+++ b/broadcastradio/1.1/utils/Utils.cpp
@@ -53,7 +53,9 @@
 static bool haveEqualIds(const ProgramSelector& a, const ProgramSelector& b,
                          const IdentifierType type) {
     if (!bothHaveId(a, b, type)) return false;
-    // TODO(b/36864090): we should check all Ids of a given type (ie. other AF), not just one
+    /* We should check all Ids of a given type (ie. other AF),
+     * but it doesn't matter for default implementation.
+     */
     auto aId = getId(a, type);
     auto bId = getId(b, type);
     return aId == bId;
diff --git a/broadcastradio/1.1/utils/include/broadcastradio-utils/Utils.h b/broadcastradio/1.1/utils/include/broadcastradio-utils/Utils.h
index a7da9fe..4d69c0a 100644
--- a/broadcastradio/1.1/utils/include/broadcastradio-utils/Utils.h
+++ b/broadcastradio/1.1/utils/include/broadcastradio-utils/Utils.h
@@ -27,6 +27,12 @@
 namespace V1_1 {
 namespace utils {
 
+// TODO(b/64115813): move it out from frameworks/base/services/core/jni/BroadcastRadio/types.h
+enum class HalRevision : uint32_t {
+    V1_0 = 1,
+    V1_1,
+};
+
 /**
  * Checks, if {@code pointer} tunes to {@channel}.
  *
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index c9f03b0..8ff9847 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -2213,7 +2213,7 @@
                                  static_cast<uint32_t>(it.width),
                                  static_cast<uint32_t>(it.height),
                                  static_cast<PixelFormat>(it.format),
-                                 0,
+                                 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                                  0,
                                  StreamRotation::ROTATION_0};
                 ::android::hardware::hidl_vec<Stream> streams = {stream};
@@ -2257,7 +2257,7 @@
                              static_cast<uint32_t>(0),
                              static_cast<uint32_t>(0),
                              static_cast<PixelFormat>(outputStreams[0].format),
-                             0,
+                             GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                              0,
                              StreamRotation::ROTATION_0};
             ::android::hardware::hidl_vec<Stream> streams = {stream};
@@ -2272,7 +2272,7 @@
                       static_cast<uint32_t>(UINT32_MAX),
                       static_cast<uint32_t>(UINT32_MAX),
                       static_cast<PixelFormat>(outputStreams[0].format),
-                      0,
+                      GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                       0,
                       StreamRotation::ROTATION_0};
             streams[0] = stream;
@@ -2288,7 +2288,7 @@
                           static_cast<uint32_t>(it.width),
                           static_cast<uint32_t>(it.height),
                           static_cast<PixelFormat>(UINT32_MAX),
-                          0,
+                          GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                           0,
                           StreamRotation::ROTATION_0};
                 streams[0] = stream;
@@ -2303,7 +2303,7 @@
                           static_cast<uint32_t>(it.width),
                           static_cast<uint32_t>(it.height),
                           static_cast<PixelFormat>(it.format),
-                          0,
+                          GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                           0,
                           static_cast<StreamRotation>(UINT32_MAX)};
                 streams[0] = stream;
@@ -2383,7 +2383,7 @@
                                            static_cast<uint32_t>(outputIter.width),
                                            static_cast<uint32_t>(outputIter.height),
                                            static_cast<PixelFormat>(outputIter.format),
-                                           0,
+                                           GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                                            0,
                                            StreamRotation::ROTATION_0};
 
@@ -2441,7 +2441,7 @@
                                             static_cast<uint32_t>(previewIter.width),
                                             static_cast<uint32_t>(previewIter.height),
                                             static_cast<PixelFormat>(previewIter.format),
-                                            0,
+                                            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                                             0,
                                             StreamRotation::ROTATION_0};
                     Stream blobStream = {streamId++,
@@ -2449,7 +2449,7 @@
                                          static_cast<uint32_t>(blobIter.width),
                                          static_cast<uint32_t>(blobIter.height),
                                          static_cast<PixelFormat>(blobIter.format),
-                                         0,
+                                         GRALLOC1_CONSUMER_USAGE_CPU_READ,
                                          0,
                                          StreamRotation::ROTATION_0};
                     ::android::hardware::hidl_vec<Stream> streams = {previewStream, blobStream};
@@ -2501,7 +2501,7 @@
                              static_cast<uint32_t>(hfrStream.width),
                              static_cast<uint32_t>(hfrStream.height),
                              static_cast<PixelFormat>(hfrStream.format),
-                             0,
+                             GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
                              0,
                              StreamRotation::ROTATION_0};
             ::android::hardware::hidl_vec<Stream> streams = {stream};
@@ -2520,7 +2520,7 @@
                       static_cast<uint32_t>(0),
                       static_cast<uint32_t>(0),
                       static_cast<PixelFormat>(hfrStream.format),
-                      0,
+                      GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
                       0,
                       StreamRotation::ROTATION_0};
             streams[0] = stream;
@@ -2535,7 +2535,7 @@
                       static_cast<uint32_t>(UINT32_MAX),
                       static_cast<uint32_t>(UINT32_MAX),
                       static_cast<PixelFormat>(hfrStream.format),
-                      0,
+                      GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
                       0,
                       StreamRotation::ROTATION_0};
             streams[0] = stream;
@@ -2550,7 +2550,7 @@
                       static_cast<uint32_t>(hfrStream.width),
                       static_cast<uint32_t>(hfrStream.height),
                       static_cast<PixelFormat>(UINT32_MAX),
-                      0,
+                      GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
                       0,
                       StreamRotation::ROTATION_0};
             streams[0] = stream;
@@ -2603,7 +2603,7 @@
                                           static_cast<uint32_t>(videoIter.width),
                                           static_cast<uint32_t>(videoIter.height),
                                           static_cast<PixelFormat>(videoIter.format),
-                                          0,
+                                          GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
                                           0,
                                           StreamRotation::ROTATION_0};
                     Stream blobStream = {streamId++,
@@ -2611,7 +2611,7 @@
                                          static_cast<uint32_t>(blobIter.width),
                                          static_cast<uint32_t>(blobIter.height),
                                          static_cast<PixelFormat>(blobIter.format),
-                                         GRALLOC_USAGE_HW_VIDEO_ENCODER,
+                                         GRALLOC1_CONSUMER_USAGE_CPU_READ,
                                          0,
                                          StreamRotation::ROTATION_0};
                     ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream};
@@ -3291,7 +3291,7 @@
             static_cast<uint32_t> (outputPreviewStreams[0].width),
             static_cast<uint32_t> (outputPreviewStreams[0].height),
             static_cast<PixelFormat> (outputPreviewStreams[0].format),
-            0, 0, StreamRotation::ROTATION_0};
+            GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0};
     ::android::hardware::hidl_vec<Stream> streams = {*previewStream};
     StreamConfiguration config = {streams,
             StreamConfigurationMode::NORMAL_MODE};
diff --git a/current.txt b/current.txt
index cc89c69..2017df5 100644
--- a/current.txt
+++ b/current.txt
@@ -190,6 +190,7 @@
 # ABI preserving changes to HALs released in Android O
 
 150a338ce11fcec70757c9675d83cf6a5d7b40d0c812741b91671fecce59eac9 android.hardware.broadcastradio@1.0::types
+dc7e6d4f537b9943e27edc4f86c5a03bb643b18f18f866f8c3c71c0ac4ea8cbc android.hardware.broadcastradio@1.0::types
 760485232f6cce07f8bb05e3475509956996b702f77415ee5bff05e2ec5a5bcc android.hardware.dumpstate@1.0::IDumpstateDevice
 e822cb7f4a1bdd45689c5e92ccd19a2201c20b771bd4b2ec1ae627e324591f9d android.hardware.radio@1.0::IRadioResponse
 28e929b453df3d9f5060af2764e6cdb123ddb893e3e86923c877f6ff7e5f02c9 android.hardware.wifi@1.0::types
diff --git a/radio/1.0/vts/OWNERS b/radio/1.0/vts/OWNERS
new file mode 100644
index 0000000..8236e94
--- /dev/null
+++ b/radio/1.0/vts/OWNERS
@@ -0,0 +1,7 @@
+# Telephony team
+amitmahajan@google.com
+sanketpadawe@google.com
+
+# VTS team
+yuexima@google.com
+yim@google.com
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index 35d97ee..4684e0f 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -79,7 +79,7 @@
                     radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
                     radioRsp->rspInfo.error == RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW ||
                     radioRsp->rspInfo.error == RadioError::OP_NOT_ALLOWED_DURING_VOICE_CALL ||
-                    CheckOEMError());
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError());
     }
 }
 
@@ -98,7 +98,10 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        EXPECT_EQ(RadioError::INVALID_CALL_ID, radioRsp->rspInfo.error);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::INVALID_CALL_ID ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT || CheckOEMError() ||
+                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE);
     }
 }
 
@@ -116,7 +119,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
-                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE);
+                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -220,6 +224,9 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        // TODO(shuoq): Will add error check when we know the expected error from QC
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
index 9e003e2..e56e3c8 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_icc.cpp
@@ -317,6 +317,7 @@
                         radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                         radioRsp->rspInfo.error == RadioError::INVALID_SIM_STATE ||
                         radioRsp->rspInfo.error == RadioError::PASSWORD_INCORRECT ||
-                        radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+                        radioRsp->rspInfo.error == RadioError::INTERNAL_ERR ||
+                        radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
         }
-}
+    }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 864f844..d93b176 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -397,7 +397,8 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE);
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::EMPTY_RECORD);
     }
 }
 
@@ -675,9 +676,11 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
+        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::RADIO_NOT_AVAILABLE ||
                     radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED ||
-                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR);
+                    radioRsp->rspInfo.error == RadioError::INTERNAL_ERR ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -695,7 +698,8 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::LCE_NOT_SUPPORTED ||
-                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -754,22 +758,24 @@
     EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
-  }
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
 
-  /* Reset back to no carrier restriction */
-  memset(&carriers, 0, sizeof(carriers));
-  carriers.allowedCarriers.resize(0);
-  carriers.excludedCarriers.resize(0);
+    /* Reset back to no carrier restriction */
+    memset(&carriers, 0, sizeof(carriers));
+    carriers.allowedCarriers.resize(0);
+    carriers.excludedCarriers.resize(0);
 
-  radio->setAllowedCarriers(++serial, true, carriers);
-  EXPECT_EQ(std::cv_status::no_timeout, wait());
-  EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-  EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+    radio->setAllowedCarriers(++serial, true, carriers);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
 
-  if (cardStatus.cardState == CardState::ABSENT) {
-      ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE || CheckGeneralError());
-  }
+    if (cardStatus.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
+                    radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
 }
 
 /*
@@ -842,4 +848,4 @@
         ASSERT_TRUE(radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
-}
\ No newline at end of file
+}
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
index 271a23a..7d74703 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_sms.cpp
@@ -36,7 +36,8 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_STATE);
+                    radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
         EXPECT_EQ(0, radioRsp->sendSmsResult.errorCode);
     }
 }
@@ -62,7 +63,8 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_STATE);
+                    radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -145,7 +147,8 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_STATE);
+                    radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -237,7 +240,8 @@
 
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() || radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE);
+                    radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -257,7 +261,8 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_SMS_FORMAT);
+                    radioRsp->rspInfo.error == RadioError::INVALID_SMS_FORMAT ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -285,7 +290,8 @@
                     radioRsp->rspInfo.error == RadioError::ENCODING_ERR ||
                     radioRsp->rspInfo.error == RadioError::NO_RESOURCES ||
                     radioRsp->rspInfo.error == RadioError::NETWORK_NOT_READY ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_SMSC_ADDRESS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_SMSC_ADDRESS ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -308,7 +314,8 @@
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
                     radioRsp->rspInfo.error == RadioError::NO_SUCH_ENTRY ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE);
+                    radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -361,7 +368,8 @@
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
                     radioRsp->rspInfo.error == RadioError::NO_SUCH_ENTRY ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_SMSC_ADDRESS);
+                    radioRsp->rspInfo.error == RadioError::INVALID_SMSC_ADDRESS ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -413,7 +421,8 @@
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
                     radioRsp->rspInfo.error == RadioError::NO_SUCH_ENTRY ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE);
+                    radioRsp->rspInfo.error == RadioError::INVALID_MODEM_STATE ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
 
@@ -434,6 +443,7 @@
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::INVALID_STATE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
index 9e51df4..da46e88 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_stk.cpp
@@ -40,24 +40,6 @@
                     radioRsp->rspInfo.error == RadioError::NONE ||
                     radioRsp->rspInfo.error == RadioError::MODEM_ERR);
     }
-
-    // Test with sending random string
-    serial = GetRandomSerialNumber();
-    content = "0";
-
-    radio->sendEnvelope(serial, content);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::NONE ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
-    }
 }
 
 /*
@@ -81,23 +63,6 @@
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp->rspInfo.error == RadioError::NONE);
     }
-
-    serial = GetRandomSerialNumber();
-
-    // Test with sending random string
-    commandResponse = "0";
-
-    radio->sendTerminalResponseToSim(serial, commandResponse);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS);
-    }
 }
 
 /*
@@ -156,22 +121,7 @@
     if (cardStatus.cardState == CardState::ABSENT) {
         ASSERT_TRUE(CheckGeneralError() ||
                     radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
-    }
-
-    // Test with sending random string
-    serial = GetRandomSerialNumber();
-    contents = "0";
-
-    radio->sendEnvelopeWithStatus(serial, contents);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp->rspInfo.serial);
-
-    if (cardStatus.cardState == CardState::ABSENT) {
-        ASSERT_TRUE(CheckGeneralError() ||
-                    radioRsp->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp->rspInfo.error == RadioError::MODEM_ERR);
+                    radioRsp->rspInfo.error == RadioError::MODEM_ERR ||
+                    radioRsp->rspInfo.error == RadioError::SIM_ABSENT);
     }
 }
diff --git a/radio/1.1/vts/OWNERS b/radio/1.1/vts/OWNERS
new file mode 100644
index 0000000..8236e94
--- /dev/null
+++ b/radio/1.1/vts/OWNERS
@@ -0,0 +1,7 @@
+# Telephony team
+amitmahajan@google.com
+sanketpadawe@google.com
+
+# VTS team
+yuexima@google.com
+yim@google.com
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
index 549b592..36fd7c2 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <radio_hidl_hal_utils_v1_1.h>
+#include <vector>
 
 /*
  * Test IRadio.setSimCardPower() for the response returned.
@@ -129,4 +130,116 @@
         ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
                     radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.startKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, startKeepalive) {
+    std::vector<KeepaliveRequest> requests = {
+        {
+            // Invalid IPv4 source address
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0 /*, 100*/},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv4 destination address
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4, 1, 2, 3, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Keepalive Type
+            static_cast<KeepaliveType>(-1),
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv6 source address
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF, 0xBD},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88, 0x44},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid IPv6 destination address
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88,
+             /*0x44*/},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Context ID (cid), this should survive the initial
+            // range checking and fail in the modem data layer
+            KeepaliveType::NATT_IPV4,
+            {192, 168, 0, 100},
+            1234,
+            {8, 8, 4, 4},
+            4500,
+            20000,
+            0xBAD,
+        },
+        {
+            // Invalid Context ID (cid), this should survive the initial
+            // range checking and fail in the modem data layer
+            KeepaliveType::NATT_IPV6,
+            {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xED,
+             0xBE, 0xEF},
+            1234,
+            {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+             0x88, 0x44},
+            4500,
+            20000,
+            0xBAD,
+        }};
+
+    for (auto req = requests.begin(); req != requests.end(); req++) {
+        int serial = GetRandomSerialNumber();
+        radio_v1_1->startKeepalive(serial, *req);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+        ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * Test IRadio.stopKeepalive() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, stopKeepalive) {
+    int serial = GetRandomSerialNumber();
+
+    radio_v1_1->stopKeepalive(serial, 0xBAD);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+
+    ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
+                radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+}
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
index dd4f1ef..c797e35 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
+++ b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
@@ -53,6 +53,7 @@
     hidl_string imsi;
     IccIoResult iccIoResult;
     int channelId;
+    KeepaliveStatus keepaliveStatus;
 
     // Sms
     SendSmsResult sendSmsResult;
@@ -567,4 +568,4 @@
    public:
     virtual void SetUp() {}
     virtual void TearDown() {}
-};
\ No newline at end of file
+};
diff --git a/radio/1.1/vts/functional/radio_response.cpp b/radio/1.1/vts/functional/radio_response.cpp
index 407b464..400ef3c 100644
--- a/radio/1.1/vts/functional/radio_response.cpp
+++ b/radio/1.1/vts/functional/radio_response.cpp
@@ -683,11 +683,16 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
-                                                        const KeepaliveStatus& /*status*/) {
+Return<void> RadioResponse_v1_1::startKeepaliveResponse(const RadioResponseInfo& info,
+                                                        const KeepaliveStatus& status) {
+    rspInfo = info;
+    keepaliveStatus = status;
+    parent_v1_1.notify();
     return Void();
 }
 
-Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+Return<void> RadioResponse_v1_1::stopKeepaliveResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_1.notify();
     return Void();
-}
\ No newline at end of file
+}
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index 55f5a87..90c36dd 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -32,6 +32,8 @@
 using ::android::hardware::wifi::offload::V1_0::IOffloadCallback;
 using ::android::hardware::wifi::offload::V1_0::ScanResult;
 using ::android::hardware::wifi::offload::V1_0::ScanParam;
+using ::android::hardware::wifi::offload::V1_0::Ssid;
+using ::android::hardware::wifi::offload::V1_0::NetworkInfo;
 using ::android::hardware::wifi::offload::V1_0::ScanFilter;
 using ::android::hardware::wifi::offload::V1_0::ScanStats;
 using ::android::hardware::wifi::offload::V1_0::OffloadStatus;
@@ -45,7 +47,8 @@
 constexpr char kOffloadCallbackSendError[] = "onError";
 
 namespace {
-const uint8_t kSsid[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid1[] = {'G', 'o', 'o', 'g', 'l', 'e'};
+const uint8_t kSsid2[] = {'X', 'f', 'i', 'n', 'i', 't', 'y'};
 const uint8_t kBssid[6] = {0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b};
 const int16_t kRssi = -60;
 const uint32_t kFrequency = 2412;
@@ -53,6 +56,10 @@
 const uint64_t kTsf = 0;
 const uint16_t kCapability = 0;
 const uint8_t kNetworkFlags = 0;
+const uint32_t kFrequency1 = 2412;
+const uint32_t kFrequency2 = 2437;
+const uint32_t kDisconnectedModeScanIntervalMs = 5000;
+const int16_t kRssiThreshold = -76;
 }
 
 class OffloadCallbackArgs {
@@ -133,7 +140,28 @@
  */
 TEST_F(WifiOffloadHidlTest, configureScans) {
     ScanParam* pScanParam = new ScanParam();
+    std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
+    pScanParam->disconnectedModeScanIntervalMs =
+        kDisconnectedModeScanIntervalMs;
+    pScanParam->frequencyList = frequencyList;
+    std::vector<Ssid> ssidList;
+    std::vector<std::vector<uint8_t>> ssids{kSsid1, kSsid2};
+    for (const auto& ssid : ssids) {
+        Ssid tmp = ssid;
+        ssidList.push_back(tmp);
+    }
+    pScanParam->ssidList = ssidList;
     ScanFilter* pScanFilter = new ScanFilter();
+    pScanFilter->rssiThreshold = kRssiThreshold;
+    std::vector<std::vector<uint8_t>> match_ssids{kSsid1, kSsid2};
+    std::vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags};
+    std::vector<NetworkInfo> preferredNetworksList;
+    for (size_t i = 0; i < security_flags.size(); i++) {
+        NetworkInfo nwInfo;
+        nwInfo.ssid = match_ssids[i];
+        nwInfo.flags = security_flags[i];
+        preferredNetworksList.push_back(nwInfo);
+    }
     const auto& result =
         HIDL_INVOKE(wifi_offload_, configureScans, *pScanParam, *pScanFilter);
     ASSERT_EQ(OffloadStatusCode::OK, result.code);
@@ -154,7 +182,7 @@
 TEST_F(WifiOffloadHidlTest, getScanResults) {
     wifi_offload_->setEventCallback(wifi_offload_cb_);
     std::vector<ScanResult> scan_results;
-    std::vector<uint8_t> ssid(kSsid, kSsid + sizeof(kSsid));
+    std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
     ScanResult scan_result;
     scan_result.tsf = kTsf;
     scan_result.rssi = kRssi;