Merge changes I51b1e596,I3aece23a into oc-mr1-dev

* changes:
  bug fix: output colorformat configuration fixed
  bug fix: android list management in dequeueMsg()
diff --git a/Android.bp b/Android.bp
index 79e8609..7ae00b6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -9,3 +9,32 @@
         "-Werror",
     ],
 }
+
+// VTS tests must link to HAL definition libraries statically.
+cc_defaults {
+    name: "VtsHalTargetTestDefaults",
+    defaults: ["hidl_defaults"],
+
+    // Lists all dependencies that can *not* be expected on the device.
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+    ],
+    group_static_libs: true,
+
+    // Lists all system dependencies that can be expected on the device.
+    shared_libs: [
+        "libbase",
+        // All the following are dependencies of any HAL definition library.
+        "libcutils",
+        "liblog",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+    ],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+
+}
diff --git a/audio/2.0/Android.bp b/audio/2.0/Android.bp
index b193c8f..cdaaa15 100644
--- a/audio/2.0/Android.bp
+++ b/audio/2.0/Android.bp
@@ -81,13 +81,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.audio@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.audio@2.0_genc++"],
     generated_headers: ["android.hardware.audio@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.audio@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
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/audio/common/2.0/Android.bp b/audio/common/2.0/Android.bp
index 39db15a..0007f44 100644
--- a/audio/common/2.0/Android.bp
+++ b/audio/common/2.0/Android.bp
@@ -32,13 +32,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.audio.common@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.audio.common@2.0_genc++"],
     generated_headers: ["android.hardware.audio.common@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.audio.common@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/audio/common/2.0/default/Android.bp b/audio/common/2.0/default/Android.bp
index 0486a5c..104bbac 100644
--- a/audio/common/2.0/default/Android.bp
+++ b/audio/common/2.0/default/Android.bp
@@ -16,6 +16,9 @@
 cc_library_shared {
     name: "android.hardware.audio.common@2.0-util",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     srcs: [
         "EffectMap.cpp",
         "HidlUtils.cpp",
diff --git a/audio/effect/2.0/Android.bp b/audio/effect/2.0/Android.bp
index a004263..fd667f0 100644
--- a/audio/effect/2.0/Android.bp
+++ b/audio/effect/2.0/Android.bp
@@ -130,13 +130,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.audio.effect@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.audio.effect@2.0_genc++"],
     generated_headers: ["android.hardware.audio.effect@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.audio.effect@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/automotive/evs/1.0/Android.bp b/automotive/evs/1.0/Android.bp
index 9ca97a7..7ae2231 100644
--- a/automotive/evs/1.0/Android.bp
+++ b/automotive/evs/1.0/Android.bp
@@ -60,13 +60,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.automotive.evs@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.automotive.evs@1.0_genc++"],
     generated_headers: ["android.hardware.automotive.evs@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.automotive.evs@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp
index e21bef0..879fe0d 100644
--- a/automotive/vehicle/2.0/Android.bp
+++ b/automotive/vehicle/2.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.automotive.vehicle@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.automotive.vehicle@2.0_genc++"],
     generated_headers: ["android.hardware.automotive.vehicle@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.automotive.vehicle@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/automotive/vehicle/2.1/Android.bp b/automotive/vehicle/2.1/Android.bp
index 9e45fb5..447c08e 100644
--- a/automotive/vehicle/2.1/Android.bp
+++ b/automotive/vehicle/2.1/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.automotive.vehicle@2.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.automotive.vehicle@2.1_genc++"],
     generated_headers: ["android.hardware.automotive.vehicle@2.1_genc++_headers"],
     export_generated_headers: ["android.hardware.automotive.vehicle@2.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/automotive/vehicle/2.1/Android.mk b/automotive/vehicle/2.1/Android.mk
index 095a1c7..3001da0 100644
--- a/automotive/vehicle/2.1/Android.mk
+++ b/automotive/vehicle/2.1/Android.mk
@@ -18,9 +18,9 @@
 
 
 #
-# Build types.hal (CommonIgnitionMonitors)
+# Build types.hal (DiagnosticFloatSensorIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/CommonIgnitionMonitors.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/DiagnosticFloatSensorIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -30,16 +30,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.CommonIgnitionMonitors
+        android.hardware.automotive.vehicle@2.1::types.DiagnosticFloatSensorIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (CompressionIgnitionMonitors)
+# Build types.hal (DiagnosticIntegerSensorIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/CompressionIgnitionMonitors.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/DiagnosticIntegerSensorIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -49,16 +49,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.CompressionIgnitionMonitors
+        android.hardware.automotive.vehicle@2.1::types.DiagnosticIntegerSensorIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (FuelSystemStatus)
+# Build types.hal (Obd2CommonIgnitionMonitors)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/FuelSystemStatus.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2CommonIgnitionMonitors.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -68,16 +68,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.FuelSystemStatus
+        android.hardware.automotive.vehicle@2.1::types.Obd2CommonIgnitionMonitors
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (FuelType)
+# Build types.hal (Obd2CompressionIgnitionMonitors)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/FuelType.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2CompressionIgnitionMonitors.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -87,16 +87,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.FuelType
+        android.hardware.automotive.vehicle@2.1::types.Obd2CompressionIgnitionMonitors
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (IgnitionMonitorKind)
+# Build types.hal (Obd2FuelSystemStatus)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/IgnitionMonitorKind.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2FuelSystemStatus.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -106,16 +106,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.IgnitionMonitorKind
+        android.hardware.automotive.vehicle@2.1::types.Obd2FuelSystemStatus
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (Obd2FloatSensorIndex)
+# Build types.hal (Obd2FuelType)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2FloatSensorIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2FuelType.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -125,16 +125,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.Obd2FloatSensorIndex
+        android.hardware.automotive.vehicle@2.1::types.Obd2FuelType
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (Obd2IntegerSensorIndex)
+# Build types.hal (Obd2IgnitionMonitorKind)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2IntegerSensorIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2IgnitionMonitorKind.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -144,16 +144,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.Obd2IntegerSensorIndex
+        android.hardware.automotive.vehicle@2.1::types.Obd2IgnitionMonitorKind
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (SecondaryAirStatus)
+# Build types.hal (Obd2SecondaryAirStatus)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/SecondaryAirStatus.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2SecondaryAirStatus.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -163,16 +163,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.SecondaryAirStatus
+        android.hardware.automotive.vehicle@2.1::types.Obd2SecondaryAirStatus
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (SparkIgnitionMonitors)
+# Build types.hal (Obd2SparkIgnitionMonitors)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/SparkIgnitionMonitors.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2SparkIgnitionMonitors.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -182,7 +182,7 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.SparkIgnitionMonitors
+        android.hardware.automotive.vehicle@2.1::types.Obd2SparkIgnitionMonitors
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
@@ -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)
@@ -358,9 +377,9 @@
 
 
 #
-# Build types.hal (CommonIgnitionMonitors)
+# Build types.hal (DiagnosticFloatSensorIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/CommonIgnitionMonitors.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/DiagnosticFloatSensorIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -370,16 +389,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.CommonIgnitionMonitors
+        android.hardware.automotive.vehicle@2.1::types.DiagnosticFloatSensorIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (CompressionIgnitionMonitors)
+# Build types.hal (DiagnosticIntegerSensorIndex)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/CompressionIgnitionMonitors.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/DiagnosticIntegerSensorIndex.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -389,16 +408,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.CompressionIgnitionMonitors
+        android.hardware.automotive.vehicle@2.1::types.DiagnosticIntegerSensorIndex
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (FuelSystemStatus)
+# Build types.hal (Obd2CommonIgnitionMonitors)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/FuelSystemStatus.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2CommonIgnitionMonitors.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -408,16 +427,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.FuelSystemStatus
+        android.hardware.automotive.vehicle@2.1::types.Obd2CommonIgnitionMonitors
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (FuelType)
+# Build types.hal (Obd2CompressionIgnitionMonitors)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/FuelType.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2CompressionIgnitionMonitors.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -427,16 +446,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.FuelType
+        android.hardware.automotive.vehicle@2.1::types.Obd2CompressionIgnitionMonitors
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (IgnitionMonitorKind)
+# Build types.hal (Obd2FuelSystemStatus)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/IgnitionMonitorKind.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2FuelSystemStatus.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -446,16 +465,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.IgnitionMonitorKind
+        android.hardware.automotive.vehicle@2.1::types.Obd2FuelSystemStatus
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (Obd2FloatSensorIndex)
+# Build types.hal (Obd2FuelType)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2FloatSensorIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2FuelType.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -465,16 +484,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.Obd2FloatSensorIndex
+        android.hardware.automotive.vehicle@2.1::types.Obd2FuelType
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (Obd2IntegerSensorIndex)
+# Build types.hal (Obd2IgnitionMonitorKind)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2IntegerSensorIndex.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2IgnitionMonitorKind.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -484,16 +503,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.Obd2IntegerSensorIndex
+        android.hardware.automotive.vehicle@2.1::types.Obd2IgnitionMonitorKind
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (SecondaryAirStatus)
+# Build types.hal (Obd2SecondaryAirStatus)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/SecondaryAirStatus.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2SecondaryAirStatus.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -503,16 +522,16 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.SecondaryAirStatus
+        android.hardware.automotive.vehicle@2.1::types.Obd2SecondaryAirStatus
 
 $(GEN): $(LOCAL_PATH)/types.hal
 	$(transform-generated-source)
 LOCAL_GENERATED_SOURCES += $(GEN)
 
 #
-# Build types.hal (SparkIgnitionMonitors)
+# Build types.hal (Obd2SparkIgnitionMonitors)
 #
-GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/SparkIgnitionMonitors.java
+GEN := $(intermediates)/android/hardware/automotive/vehicle/V2_1/Obd2SparkIgnitionMonitors.java
 $(GEN): $(HIDL)
 $(GEN): PRIVATE_HIDL := $(HIDL)
 $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
@@ -522,7 +541,7 @@
         -Ljava \
         -randroid.hardware:hardware/interfaces \
         -randroid.hidl:system/libhidl/transport \
-        android.hardware.automotive.vehicle@2.1::types.SparkIgnitionMonitors
+        android.hardware.automotive.vehicle@2.1::types.Obd2SparkIgnitionMonitors
 
 $(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/common/include/vhal_v2_1/Obd2SensorStore.h b/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h
index 6c44626..8000695 100644
--- a/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h
+++ b/automotive/vehicle/2.1/default/common/include/vhal_v2_1/Obd2SensorStore.h
@@ -38,12 +38,12 @@
                     size_t numVendorFloatSensors);
 
     // Stores an integer-valued sensor.
-    V2_0::StatusCode setIntegerSensor(Obd2IntegerSensorIndex index, int32_t value);
+    V2_0::StatusCode setIntegerSensor(DiagnosticIntegerSensorIndex index, int32_t value);
     // Stores an integer-valued sensor.
     V2_0::StatusCode setIntegerSensor(size_t index, int32_t value);
 
     // Stores a float-valued sensor.
-    V2_0::StatusCode setFloatSensor(Obd2FloatSensorIndex index, float value);
+    V2_0::StatusCode setFloatSensor(DiagnosticFloatSensorIndex index, float value);
     // Stores a float-valued sensor.
     V2_0::StatusCode setFloatSensor(size_t index, float value);
 
diff --git a/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp b/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp
index f4c63a9..8705e00 100644
--- a/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp
+++ b/automotive/vehicle/2.1/default/common/src/Obd2SensorStore.cpp
@@ -56,9 +56,12 @@
 
 Obd2SensorStore::Obd2SensorStore(size_t numVendorIntegerSensors,
                                  size_t numVendorFloatSensors) {
+        using V2_0::toInt;
         // because the last index is valid *inclusive*
-        const size_t numSystemIntegerSensors = V2_0::toInt(Obd2IntegerSensorIndex::LAST_SYSTEM_INDEX)+1;
-        const size_t numSystemFloatSensors = V2_0::toInt(Obd2FloatSensorIndex::LAST_SYSTEM_INDEX)+1;
+        const size_t numSystemIntegerSensors =
+            toInt(DiagnosticIntegerSensorIndex::LAST_SYSTEM_INDEX)+1;
+        const size_t numSystemFloatSensors =
+            toInt(DiagnosticFloatSensorIndex::LAST_SYSTEM_INDEX)+1;
         mIntegerSensors = std::vector<int32_t>(
             numSystemIntegerSensors+numVendorIntegerSensors, 0);
         mFloatSensors = std::vector<float>(
@@ -66,11 +69,11 @@
         mSensorsBitmask.resize(mIntegerSensors.size()+mFloatSensors.size());
 }
 
-V2_0::StatusCode Obd2SensorStore::setIntegerSensor(Obd2IntegerSensorIndex index,
+V2_0::StatusCode Obd2SensorStore::setIntegerSensor(DiagnosticIntegerSensorIndex index,
     int32_t value) {
     return setIntegerSensor(V2_0::toInt(index), value);
 }
-V2_0::StatusCode Obd2SensorStore::setFloatSensor(Obd2FloatSensorIndex index,
+V2_0::StatusCode Obd2SensorStore::setFloatSensor(DiagnosticFloatSensorIndex index,
     float value) {
     return setFloatSensor(V2_0::toInt(index), value);
 }
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/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
index 4faccbd..568d623 100644
--- a/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
+++ b/automotive/vehicle/2.1/default/impl/vhal_v2_1/EmulatedVehicleHal.cpp
@@ -37,85 +37,86 @@
 static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(
         size_t numVendorIntegerSensors,
         size_t numVendorFloatSensors) {
+    using V2_0::toInt;
     std::unique_ptr<Obd2SensorStore> sensorStore(new Obd2SensorStore(
             numVendorIntegerSensors, numVendorFloatSensors));
 
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::FUEL_SYSTEM_STATUS,
-        V2_0::toInt(FuelSystemStatus::CLOSED_LOOP));
+        DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
+        toInt(Obd2FuelSystemStatus::CLOSED_LOOP));
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0);
+        DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::IGNITION_MONITORS_SUPPORTED,
-        V2_0::toInt(IgnitionMonitorKind::SPARK));
-    sensorStore->setIntegerSensor(Obd2IntegerSensorIndex::IGNITION_SPECIFIC_MONITORS,
-        CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
-        CommonIgnitionMonitors::MISFIRE_AVAILABLE |
-        SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
-        SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE);
+        DiagnosticIntegerSensorIndex::IGNITION_MONITORS_SUPPORTED,
+        toInt(Obd2IgnitionMonitorKind::SPARK));
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_SPECIFIC_MONITORS,
+        Obd2CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
+        Obd2CommonIgnitionMonitors::MISFIRE_AVAILABLE |
+        Obd2SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
+        Obd2SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35);
+        DiagnosticIntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS,
-        V2_0::toInt(SecondaryAirStatus::FROM_OUTSIDE_OR_OFF));
+        DiagnosticIntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS,
+        toInt(Obd2SecondaryAirStatus::FROM_OUTSIDE_OR_OFF));
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1);
+        DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500);
+        DiagnosticIntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0);
+        DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51);
+        DiagnosticIntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365);
+        DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30);
+        DiagnosticIntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12);
+        DiagnosticIntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18);
+        DiagnosticIntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1);
+        DiagnosticIntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1);
     sensorStore->setIntegerSensor(
-        Obd2IntegerSensorIndex::FUEL_TYPE, V2_0::toInt(FuelType::GASOLINE));
+        DiagnosticIntegerSensorIndex::FUEL_TYPE, V2_0::toInt(Obd2FuelType::GASOLINE));
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153);
+        DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16);
+        DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16);
+        DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16);
+        DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16);
+        DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5);
+        DiagnosticFloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::ENGINE_RPM, 1250.);
+        DiagnosticFloatSensorIndex::ENGINE_RPM, 1250.);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::VEHICLE_SPEED, 40.);
+        DiagnosticFloatSensorIndex::VEHICLE_SPEED, 40.);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::TIMING_ADVANCE, 2.5);
+        DiagnosticFloatSensorIndex::TIMING_ADVANCE, 2.5);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::THROTTLE_POSITION, 19.75);
+        DiagnosticFloatSensorIndex::THROTTLE_POSITION, 19.75);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265);
+        DiagnosticFloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824);
+        DiagnosticFloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE, -0.373);
+        DiagnosticFloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE, -0.373);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1, 190.);
+        DiagnosticFloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1, 190.);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.);
+        DiagnosticFloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306);
+        DiagnosticFloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188);
+        DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094);
+        DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094);
     sensorStore->setFloatSensor(
-        Obd2FloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024);
+        DiagnosticFloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024);
 
     return sensorStore;
 }
diff --git a/automotive/vehicle/2.1/types.hal b/automotive/vehicle/2.1/types.hal
index cea7f1b..2e361a3 100644
--- a/automotive/vehicle/2.1/types.hal
+++ b/automotive/vehicle/2.1/types.hal
@@ -50,16 +50,11 @@
      *  configArray[3] = micrometers per rear right wheel tick
      *  configArray[4] = micrometers per rear left wheel tick
      *
-     * NOTE:  If a wheel is not supported, its value shall always be set to
-     *          LONG_MAX = 9223372036854775807.
+     * NOTE:  If a wheel is not supported, its value shall always be set to 0.
      *
      * VehiclePropValue.timestamp must be correctly filled in.
      *
-     * Vendors must specify wheels that support this sensor in
-     * VehiclePropConfig.configFlags. The format of this field is a bitset of
-     * values from Wheel enum.
-     *
-     * @change_mode VehiclePropertyChangeMode:ON_CHANGE |VehiclePropertyChangeMode:CONTINUOUS
+     * @change_mode VehiclePropertyChangeMode:CONTINUOUS
      * @access VehiclePropertyAccess:READ
      */
     WHEEL_TICK = (
@@ -95,9 +90,8 @@
     /**
      * Automatic re-circulation on/off
      *
-     * IVehicle#set may return StatusCode::NOT_AVAILABLE and IVehicle#get is not
-     * guaranteed to work if HVAC unit is off.  See HVAC_POWER_ON property for
-     * details.
+     * IVehicle#set and IVehicle#get must return StatusCode::NOT_AVAILABLE when HVAC unit is off.
+     * See HVAC_POWER_ON property for details.
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ_WRITE
@@ -119,6 +113,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 +127,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 +174,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 +208,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 +226,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
@@ -260,8 +249,8 @@
       | VehicleArea:GLOBAL),
 };
 
-/** The status of a fuel system as described by the OBD2 specification. */
-enum FuelSystemStatus : int32_t {
+/** The status of the vehicle's fuel system. */
+enum Obd2FuelSystemStatus : int32_t {
   OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 1,
   CLOSED_LOOP = 2,
   OPEN_ENGINE_LOAD_OR_DECELERATION = 4,
@@ -270,13 +259,13 @@
 };
 
 /** Defines which ignition monitors are available to be read. */
-enum IgnitionMonitorKind : int32_t {
+enum Obd2IgnitionMonitorKind : int32_t {
   SPARK = 0,
   COMPRESSION = 1,
 };
 
 /** These ignition monitors are common to both SPARK and COMPRESSION. */
-enum CommonIgnitionMonitors : int32_t {
+enum Obd2CommonIgnitionMonitors : int32_t {
   COMPONENTS_AVAILABLE = 0x1 << 0,
   COMPONENTS_INCOMPLETE = 0x1 << 1,
 
@@ -288,7 +277,7 @@
 };
 
 /** Ignition monitors available for SPARK vehicles. */
-enum SparkIgnitionMonitors : CommonIgnitionMonitors {
+enum Obd2SparkIgnitionMonitors : Obd2CommonIgnitionMonitors {
   EGR_AVAILABLE = 0x1 << 6,
   EGR_INCOMPLETE = 0x1 << 7,
 
@@ -315,7 +304,7 @@
 };
 
 /** Ignition monitors only available for COMPRESSION vehicles. */
-enum CompressionIgnitionMonitors : CommonIgnitionMonitors {
+enum Obd2CompressionIgnitionMonitors : Obd2CommonIgnitionMonitors {
   EGR_OR_VVT_AVAILABLE = 0x1 << 6,
   EGR_OR_VVT_INCOMPLETE = 0x1 << 7,
 
@@ -328,21 +317,23 @@
   BOOST_PRESSURE_AVAILABLE = 0x1 << 12,
   BOOST_PRESSURE_INCOMPLETE = 0x1 << 13,
 
-  NOx_SCR__AVAILABLE = 0x1 << 14,
+  NOx_SCR_AVAILABLE = 0x1 << 14,
   NOx_SCR_INCOMPLETE = 0x1 << 15,
 
   NMHC_CATALYST_AVAILABLE = 0x1 << 16,
   NMHC_CATALYST_INCOMPLETE = 0x1 << 17,
 };
 
-enum SecondaryAirStatus : int32_t {
+/** The status of the vehicle's secondary air system. */
+enum Obd2SecondaryAirStatus : int32_t {
   UPSTREAM = 1,
   DOWNSTREAM_OF_CATALYCIC_CONVERTER = 2,
   FROM_OUTSIDE_OR_OFF = 4,
   PUMP_ON_FOR_DIAGNOSTICS = 8,
 };
 
-enum FuelType : int32_t {
+/** The fuel type(s) supported by a vehicle. */
+enum Obd2FuelType : int32_t {
   NOT_AVAILABLE = 0,
   GASOLINE = 1,
   METHANOL = 2,
@@ -376,7 +367,7 @@
  * expect a comment by the property definition describing the enum to look at for the mapping.
  * Any value greater than the last reserved index is available to vendors to map their extensions.
  */
-enum Obd2IntegerSensorIndex : int32_t {
+enum DiagnosticIntegerSensorIndex : int32_t {
   /** refer to FuelSystemStatus for a description of this value. */
   FUEL_SYSTEM_STATUS = 0,
   MALFUNCTION_INDICATOR_LIGHT_ON = 1,
@@ -431,7 +422,7 @@
  * The ordering of the values is taken from the OBD2 specification.
  * Any value greater than the last reserved index is available to vendors to map their extensions.
  */
-enum Obd2FloatSensorIndex : int32_t {
+enum DiagnosticFloatSensorIndex : int32_t {
   CALCULATED_ENGINE_LOAD = 0,
   ENGINE_COOLANT_TEMPERATURE = 1,
   SHORT_TERM_FUEL_TRIM_BANK1 = 2,
@@ -507,102 +498,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/biometrics/fingerprint/2.1/Android.bp b/biometrics/fingerprint/2.1/Android.bp
index c16fd78..3898da5 100644
--- a/biometrics/fingerprint/2.1/Android.bp
+++ b/biometrics/fingerprint/2.1/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.biometrics.fingerprint@2.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.biometrics.fingerprint@2.1_genc++"],
     generated_headers: ["android.hardware.biometrics.fingerprint@2.1_genc++_headers"],
     export_generated_headers: ["android.hardware.biometrics.fingerprint@2.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/bluetooth/1.0/Android.bp b/bluetooth/1.0/Android.bp
index 48159b3..c883c59 100644
--- a/bluetooth/1.0/Android.bp
+++ b/bluetooth/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.bluetooth@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.bluetooth@1.0_genc++"],
     generated_headers: ["android.hardware.bluetooth@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.bluetooth@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/bluetooth/1.0/vts/functional/Android.bp b/bluetooth/1.0/vts/functional/Android.bp
index cd2be44..2e60588 100644
--- a/bluetooth/1.0/vts/functional/Android.bp
+++ b/bluetooth/1.0/vts/functional/Android.bp
@@ -16,24 +16,10 @@
 
 cc_test {
     name: "VtsHalBluetoothV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalBluetoothV1_0TargetTest.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
-        "android.hardware.bluetooth@1.0",
-    ],
     static_libs: [
-        "VtsHalHidlTargetTestBase",
+        "android.hardware.bluetooth@1.0",
         "libbluetooth-types",
     ],
-    cflags: [
-        "-O0",
-        "-g",
-    ],
 }
diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp
index de42647..4e4efa3 100644
--- a/boot/1.0/Android.bp
+++ b/boot/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.boot@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.boot@1.0_genc++"],
     generated_headers: ["android.hardware.boot@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.boot@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/broadcastradio/1.0/Android.bp b/broadcastradio/1.0/Android.bp
index f0c4b22..5b8e239 100644
--- a/broadcastradio/1.0/Android.bp
+++ b/broadcastradio/1.0/Android.bp
@@ -60,13 +60,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.broadcastradio@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.broadcastradio@1.0_genc++"],
     generated_headers: ["android.hardware.broadcastradio@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.broadcastradio@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
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/Android.bp b/broadcastradio/1.1/Android.bp
index 3b50416..12e23d6 100644
--- a/broadcastradio/1.1/Android.bp
+++ b/broadcastradio/1.1/Android.bp
@@ -60,13 +60,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.broadcastradio@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.broadcastradio@1.1_genc++"],
     generated_headers: ["android.hardware.broadcastradio@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.broadcastradio@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/broadcastradio/1.1/IBroadcastRadio.hal b/broadcastradio/1.1/IBroadcastRadio.hal
index 9bde361..dadba2a 100644
--- a/broadcastradio/1.1/IBroadcastRadio.hal
+++ b/broadcastradio/1.1/IBroadcastRadio.hal
@@ -31,19 +31,34 @@
      * Fetch image from radio module.
      *
      * This call is meant to make V1_0::MetaData lightweight - instead of
-     * passing image data blob in MetadataType.RAW field, only identifier is
-     * passed, so the client may cache images or even not fetch them.
+     * passing an image data blob in the MetadataType.RAW field, the HAL
+     * implementation only passes the identifier, so the client may cache images
+     * or even not fetch them.
      *
-     * Identifier may be any arbitrary number - sequential, sha256 prefix,
+     * The identifier may be any arbitrary number - sequential, sha256 prefix,
      * or any other unique value selected by the vendor.
      *
      * The data should be a valid PNG, JPEG, GIF or BMP file.
-     * Invalid format must be handled gracefully as if the image was missing.
+     * Image data with an invalid format must be handled gracefully in the same
+     * way as a missing image.
+     *
+     * The image identifier may become invalid after some time from passing it
+     * with metadata struct (due to resource cleanup at the HAL implementation).
+     * However, it must remain valid for a currently tuned program at least
+     * until currentProgramInfoChanged or programListChanged is called and
+     * metadata changes for the current program.
+     *
+     * There is still a race condition possible (if the HAL deletes the old
+     * image immediately after notifying about the new one) between
+     * currentProgramInfoChanged callback propagating through the framework and
+     * the HAL implementation removing previous image. In such case, client
+     * application may expect the new currentProgramInfoChanged callback with
+     * updated image identifier.
      *
      * @param id Identifier of an image;
      *           value of 0 is reserved and should be treated as invalid image.
      * @return image A binary blob with image data
-     *               or zero-length vector if identifier doesn't exists.
+     *               or a zero-length vector if identifier doesn't exist.
      */
     getImage(int32_t id) generates (vec<uint8_t> image);
 };
diff --git a/broadcastradio/1.1/IBroadcastRadioFactory.hal b/broadcastradio/1.1/IBroadcastRadioFactory.hal
index fce1cc0..edf78ff 100644
--- a/broadcastradio/1.1/IBroadcastRadioFactory.hal
+++ b/broadcastradio/1.1/IBroadcastRadioFactory.hal
@@ -19,8 +19,10 @@
 import @1.0::IBroadcastRadioFactory;
 
 /**
- * To use 1.1 features you must cast specific interfaces after being returned from 1.0 HAL,
- * for example V1_1::ITuner::castFrom() after retrieving it from IBroadcastRadio::openTuner().
+ * To use 1.1 features you must cast specific interfaces returned from the
+ * 1.0 HAL. For example V1_0::IBroadcastRadio::openTuner() returns V1_0::ITuner,
+ * which can be cast with V1_1::ITuner::castFrom() call.
+ *
  * The 1.1 server must always return the 1.1 version of specific interface.
  */
 interface IBroadcastRadioFactory extends @1.0::IBroadcastRadioFactory {
diff --git a/broadcastradio/1.1/ITuner.hal b/broadcastradio/1.1/ITuner.hal
index a5c569a..b20c5f4 100644
--- a/broadcastradio/1.1/ITuner.hal
+++ b/broadcastradio/1.1/ITuner.hal
@@ -39,7 +39,7 @@
      *                INVALID_ARGUMENTS if invalid arguments are passed.
      *                NOT_INITIALIZED if another error occurs.
      */
-    tune_1_1(ProgramSelector program) generates (Result result);
+    tuneByProgramSelector(ProgramSelector program) generates (Result result);
 
     /**
      * Cancels announcement.
@@ -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,
@@ -99,10 +106,8 @@
      * This call does not trigger actual scan, but operates on the list cached
      * internally at the driver level.
      *
-     * @param filter vendor-specific filter for the stations to be retrieved.
-     *               An empty string MUST result in full list.
-     *               Client application MUST verify vendor/product name
-     *               before setting this parameter to anything else.
+     * @param vendorFilter vendor-specific filter for the stations to be retrieved.
+     *               An empty vector MUST result in full list for a given tuner.
      * @return result OK if the list was successfully retrieved.
      *                INVALID_ARGUMENTS if invalid arguments are passed
      *                NOT_READY if the scan is in progress.
@@ -111,23 +116,10 @@
      *                NOT_INITIALIZED if any other error occurs.
      * @return programList List of stations available for user.
      */
-    getProgramList(string filter)
+    getProgramList(vec<VendorKeyValue> vendorFilter)
         generates (ProgramListResult result, vec<ProgramInfo> programList);
 
     /**
-     * Checks, if the analog playback is forced, see setAnalogForced.
-     *
-     * The isForced value is only valid if result was OK.
-     *
-     * @return result OK if the call succeeded and isForced is valid.
-     *                INVALID_STATE if the switch is not supported at current
-     *                configuration.
-     *                NOT_INITIALIZED if any other error occurs.
-     * @return isForced true if analog is forced, false otherwise.
-     */
-    isAnalogForced() generates (Result result, bool isForced);
-
-    /**
      * Forces the analog playback for the supporting radio technology.
      *
      * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
@@ -143,4 +135,17 @@
      *                NOT_INITIALIZED if any other error occurs.
      */
     setAnalogForced(bool isForced) generates (Result result);
+
+    /**
+     * Checks, if the analog playback is forced, see setAnalogForced.
+     *
+     * The isForced value is only valid if result was OK.
+     *
+     * @return result OK if the call succeeded and isForced is valid.
+     *                INVALID_STATE if the switch is not supported at current
+     *                configuration.
+     *                NOT_INITIALIZED if any other error occurs.
+     * @return isForced true if analog is forced, false otherwise.
+     */
+    isAnalogForced() generates (Result result, bool isForced);
 };
diff --git a/broadcastradio/1.1/ITunerCallback.hal b/broadcastradio/1.1/ITunerCallback.hal
index b1c5b01..8bf5b7f 100644
--- a/broadcastradio/1.1/ITunerCallback.hal
+++ b/broadcastradio/1.1/ITunerCallback.hal
@@ -29,9 +29,13 @@
      * Method called by the HAL when a tuning operation completes
      * following a step(), scan() or tune() command.
      *
-     * This callback supersedes V1_0::tuneComplete. For performance reasons,
-     * the 1.0 callback may not be called when HAL implementation detects 1.1
-     * client (by casting V1_0::ITunerCallback to V1_1::ITunerCallback).
+     * This callback supersedes V1_0::tuneComplete.
+     * The 1.0 callback must not be called when HAL implementation detects
+     * 1.1 client (by casting V1_0::ITunerCallback to V1_1::ITunerCallback).
+     *
+     * In case of success, currentProgramInfoChanged must be called too.
+     * It means the success case may (or may not) be handled by the client in
+     * currentProgramInfoChanged, instead of here.
      *
      * @param result OK if tune succeeded or TIMEOUT in case of time out.
      * @param selector A ProgramSelector structure describing the tuned station.
@@ -39,17 +43,6 @@
     oneway tuneComplete_1_1(Result result, ProgramSelector selector);
 
     /**
-     * Method called by the HAL when a frequency switch occurs.
-     *
-     * This callback supersedes V1_0::afSwitch. For performance reasons,
-     * the 1.0 callback may not be called when HAL implementation detects 1.1
-     * client (by casting V1_0::ITunerCallback to V1_1::ITunerCallback).
-     *
-     * @param selector A ProgramSelector structure describing the tuned station.
-     */
-    oneway afSwitch_1_1(ProgramSelector selector);
-
-    /**
      * Called by the HAL when background scan feature becomes available or not.
      *
      * @param isAvailable true, if the tuner turned temporarily background-
@@ -73,6 +66,9 @@
      * call it immediately, ie. it may wait for a short time to accumulate
      * multiple list change notifications into a single event.
      *
+     * This callback is only for notifying about insertions and deletions,
+     * not about metadata changes.
+     *
      * It may be triggered either by an explicitly issued background scan,
      * or a scan issued by the device internally.
      *
@@ -89,10 +85,12 @@
      *
      * This may be called together with tuneComplete_1_1 or afSwitch_1_1.
      *
-     * This callback supersedes V1_0::tuneComplete, V1_0::afSwitch and
-     * newMetadata. For performance reasons, these callbacks may not be called
-     * when HAL implementation detects 1.1 client (by casting
-     * V1_0::ITunerCallback to V1_1::ITunerCallback).
+     * This callback supersedes V1_0::newMetadata and V1_0::afSwitch;
+     * partly V1_0::tuneComplete.
+     * 1.0 callbacks must not be called when HAL implementation detects
+     * 1.1 client (by casting V1_0::ITunerCallback to V1_1::ITunerCallback).
+     *
+     * @param info current program information
      */
-    oneway programInfoChanged();
+    oneway currentProgramInfoChanged(ProgramInfo info);
 };
diff --git a/broadcastradio/1.1/default/BroadcastRadio.cpp b/broadcastradio/1.1/default/BroadcastRadio.cpp
index 7916407..ce7a10f 100644
--- a/broadcastradio/1.1/default/BroadcastRadio.cpp
+++ b/broadcastradio/1.1/default/BroadcastRadio.cpp
@@ -91,17 +91,19 @@
     prop10.numAudioSources = 1;
     prop10.supportsCapture = false;
     prop11.supportsBackgroundScanning = false;
-    prop11.supportedProgramTypes = vector<uint32_t>({
+    prop11.supportedProgramTypes = hidl_vec<uint32_t>({
         static_cast<uint32_t>(ProgramType::AM), static_cast<uint32_t>(ProgramType::FM),
         static_cast<uint32_t>(ProgramType::AM_HD), static_cast<uint32_t>(ProgramType::FM_HD),
     });
-    prop11.supportedIdentifierTypes = vector<uint32_t>({
+    prop11.supportedIdentifierTypes = hidl_vec<uint32_t>({
         static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY),
         static_cast<uint32_t>(IdentifierType::RDS_PI),
         static_cast<uint32_t>(IdentifierType::HD_STATION_ID_EXT),
         static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL),
     });
-    prop11.vendorInfo = "dummy";
+    prop11.vendorInfo = hidl_vec<VendorKeyValue>({
+        {"com.google.dummy", "dummy"},
+    });
 
     prop10.bands.resize(mConfig.amFmBands.size());
     for (size_t i = 0; i < mConfig.amFmBands.size(); i++) {
@@ -143,7 +145,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/OWNERS b/broadcastradio/1.1/default/OWNERS
new file mode 100644
index 0000000..0c27b71
--- /dev/null
+++ b/broadcastradio/1.1/default/OWNERS
@@ -0,0 +1,4 @@
+# Automotive team
+egranata@google.com
+keunyoung@google.com
+twasilczyk@google.com
diff --git a/broadcastradio/1.1/default/Tuner.cpp b/broadcastradio/1.1/default/Tuner.cpp
index 133593e..87964d3 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,13 +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()) {
-    // 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);
@@ -65,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;
 
@@ -76,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);
     };
@@ -86,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
@@ -108,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);
@@ -133,17 +144,16 @@
         mCallback->tuneComplete(Result::OK, mCurrentProgramInfo.base);
     } else {
         mCallback1_1->tuneComplete_1_1(Result::OK, mCurrentProgramInfo.selector);
+        mCallback1_1->currentProgramInfoChanged(mCurrentProgramInfo);
     }
 }
 
 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;
@@ -195,17 +205,20 @@
 
 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");
         return Result::NOT_INITIALIZED;
     }
 
-    ALOGW_IF(!mIsAmfmConfigSet, "AM/FM config not set");
-    if (!mIsAmfmConfigSet) return Result::INVALID_STATE;
+    if (!mIsAmfmConfigSet) {
+        ALOGW("AM/FM config not set");
+        return Result::INVALID_STATE;
+    }
     mIsTuneCompleted = false;
 
     auto task = [this, direction]() {
@@ -238,22 +251,34 @@
         lock_guard<mutex> lk(mMut);
         band = mAmfmConfig.type;
     }
-    return tune_1_1(utils::make_selector(band, channel, subChannel));
+    return tuneByProgramSelector(utils::make_selector(band, channel, subChannel));
 }
 
-Return<Result> Tuner::tune_1_1(const ProgramSelector& sel) {
+Return<Result> Tuner::tuneByProgramSelector(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");
-        if (!mIsAmfmConfigSet) return Result::INVALID_STATE;
+    // checking if ProgramSelector is valid
+    auto programType = utils::getType(sel);
+    if (utils::isAmFm(programType)) {
+        if (!mIsAmfmConfigSet) {
+            ALOGW("AM/FM config not set");
+            return Result::INVALID_STATE;
+        }
 
         auto freq = utils::getId(sel, IdentifierType::AMFM_FREQUENCY);
         if (freq < mAmfmConfig.lowerLimit || freq > mAmfmConfig.upperLimit) {
             return Result::INVALID_ARGUMENTS;
         }
+    } else if (programType == ProgramType::DAB) {
+        if (!utils::hasId(sel, IdentifierType::DAB_SIDECC)) return Result::INVALID_ARGUMENTS;
+    } else if (programType == ProgramType::DRMO) {
+        if (!utils::hasId(sel, IdentifierType::DRMO_SERVICE_ID)) return Result::INVALID_ARGUMENTS;
+    } else if (programType == ProgramType::SXM) {
+        if (!utils::hasId(sel, IdentifierType::SXM_SERVICE_ID)) return Result::INVALID_ARGUMENTS;
+    } else {
+        return Result::INVALID_ARGUMENTS;
     }
 
     mIsTuneCompleted = false;
@@ -268,12 +293,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;
 }
 
@@ -286,49 +317,60 @@
 
 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_vec<VendorKeyValue>& vendorFilter,
+                                   getProgramList_cb _hidl_cb) {
+    ALOGV("%s(%s)", __func__, toString(vendorFilter).substr(0, 100).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<Result> Tuner::setAnalogForced(bool isForced) {
+    ALOGV("%s", __func__);
+    lock_guard<mutex> lk(mMut);
+    if (mIsClosed) return Result::NOT_INITIALIZED;
+
+    mIsAnalogForced = isForced;
+    return Result::OK;
 }
 
 Return<void> Tuner::isAnalogForced(isAnalogForced_cb _hidl_cb) {
     ALOGV("%s", __func__);
-    // TODO(b/36864090): implement
-    _hidl_cb(Result::INVALID_STATE, false);
-    return Void();
-}
+    lock_guard<mutex> lk(mMut);
 
-Return<Result> Tuner::setAnalogForced(bool isForced __unused) {
-    ALOGV("%s", __func__);
-    // TODO(b/36864090): implement
-    return Result::INVALID_STATE;
+    if (mIsClosed) {
+        _hidl_cb(Result::NOT_INITIALIZED, false);
+    } else {
+        _hidl_cb(Result::OK, mIsAnalogForced);
+    }
+    return {};
 }
 
 }  // namespace implementation
diff --git a/broadcastradio/1.1/default/Tuner.h b/broadcastradio/1.1/default/Tuner.h
index 2222e5a..07d3189 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();
 
@@ -39,35 +39,36 @@
     virtual Return<Result> scan(V1_0::Direction direction, bool skipSubChannel) override;
     virtual Return<Result> step(V1_0::Direction direction, bool skipSubChannel) override;
     virtual Return<Result> tune(uint32_t channel, uint32_t subChannel) override;
-    virtual Return<Result> tune_1_1(const ProgramSelector& program) override;
+    virtual Return<Result> tuneByProgramSelector(const ProgramSelector& program) override;
     virtual Return<Result> cancel() override;
     virtual Return<Result> cancelAnnouncement() override;
     virtual Return<void> getProgramInformation(getProgramInformation_cb _hidl_cb) override;
     virtual Return<void> getProgramInformation_1_1(getProgramInformation_1_1_cb _hidl_cb) override;
     virtual Return<ProgramListResult> startBackgroundScan() override;
-    virtual Return<void> getProgramList(const hidl_string& filter,
+    virtual Return<void> getProgramList(const hidl_vec<VendorKeyValue>& filter,
                                         getProgramList_cb _hidl_cb) override;
-    virtual Return<void> isAnalogForced(isAnalogForced_cb _hidl_cb) override;
     virtual Return<Result> setAnalogForced(bool isForced) override;
+    virtual Return<void> isAnalogForced(isAnalogForced_cb _hidl_cb) override;
 
    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;
     ProgramSelector mCurrentProgram = {};
     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..7977391 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,13 @@
         {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),
+    });
+
+    info11.vendorInfo = hidl_vec<VendorKeyValue>({
+        {"com.google.dummy", "dummy"},
+        {"com.google.dummy.VirtualProgram", std::to_string(reinterpret_cast<uintptr_t>(this))},
     });
 
     return info11;
@@ -89,6 +90,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/tests/OWNERS b/broadcastradio/1.1/tests/OWNERS
new file mode 100644
index 0000000..aa5ce82
--- /dev/null
+++ b/broadcastradio/1.1/tests/OWNERS
@@ -0,0 +1,8 @@
+# Automotive team
+egranata@google.com
+keunyoung@google.com
+twasilczyk@google.com
+
+# VTS team
+ryanjcampbell@google.com
+yim@google.com
diff --git a/broadcastradio/1.1/types.hal b/broadcastradio/1.1/types.hal
index 4034d8b..8b8fc6f 100644
--- a/broadcastradio/1.1/types.hal
+++ b/broadcastradio/1.1/types.hal
@@ -56,6 +56,24 @@
     TRAFFIC_ANNOUNCEMENT = 1 << 3,
 };
 
+/**
+ * A key-value pair for vendor-specific information to be passed as-is through
+ * Android framework to the front-end application.
+ */
+struct VendorKeyValue {
+    /**
+     * Key must be prefixed with unique vendor Java-style namespace,
+     * eg. 'com.somecompany.parameter1'.
+     */
+    string key;
+
+    /**
+     * Value must be passed through the framework without any changes.
+     * Format of this string can vary across vendors.
+     */
+    string value;
+};
+
 struct Properties {
     @1.0::Properties base;
 
@@ -89,16 +107,12 @@
     vec<uint32_t> supportedIdentifierTypes;
 
     /**
-     * Opaque vendor-specific string, to be passed to front-end without changes.
-     * Format of this string can vary across vendors.
+     * Vendor-specific information.
      *
-     * It may be used for extra features, that's not supported by a platform,
-     * for example: "preset-slots=6;ultra-hd-capable=false".
-     *
-     * Front-end application MUST verify vendor/product name from the
-     * @1.0::Properties struct before doing any interpretation of this value.
+     * It may be used for extra features, not supported by the platform,
+     * for example: com.me.preset-slots=6; com.me.ultra-hd-capable=false.
      */
-    string vendorInfo;
+    vec<VendorKeyValue> vendorInfo;
 };
 
 /**
@@ -114,11 +128,14 @@
 /**
  * Type of a radio technology.
  *
+ * VENDOR program types must be opaque to the framework.
+ *
  * There are multiple VENDOR program types just to make vendor implementation
  * easier with multiple properitary radio technologies. They are treated the
  * same by the framework.
  *
  * All other values are reserved for future use.
+ * Values not matching any enumerated constant must be ignored.
  */
 enum ProgramType : uint32_t {
     AM = 1,  // analogue AM radio (with or without RDS)
@@ -128,10 +145,10 @@
     DAB,     // Digital audio broadcasting
     DRMO,    // Digital Radio Mondiale
     SXM,     // SiriusXM Satellite Radio
-    VENDOR1, // Vendor-specific, not synced across devices.
-    VENDOR2, // Vendor-specific, not synced across devices.
-    VENDOR3, // Vendor-specific, not synced across devices.
-    VENDOR4, // Vendor-specific, not synced across devices.
+
+    // Vendor-specific, not synced across devices.
+    VENDOR_START = 1000,
+    VENDOR_END = 1999,
 };
 
 /**
@@ -141,10 +158,13 @@
  * it for secondary IDs. For example, a satellite program may set AM/FM fallback
  * frequency, if a station broadcasts both via satellite and AM/FM.
  *
+ * VENDOR identifier types must be opaque to the framework.
+ *
  * The value format for each (but VENDOR_PRIMARY) identifier is strictly defined
  * to maintain interoperability between devices made by different vendors.
  *
  * All other values are reserved for future use.
+ * Values not matching any enumerated constant must be ignored.
  */
 enum IdentifierType : uint32_t {
     AMFM_FREQUENCY = 1,  // kHz
@@ -194,12 +214,12 @@
      * Primary identifier for vendor-specific radio technology.
      * The value format is determined by a vendor.
      *
-     * It must not be used in any other programType than VENDORx.
+     * It must not be used in any other programType than corresponding VENDOR
+     * type between VENDOR_START and VENDOR_END (eg. identifier type 1015 must
+     * not be used in any program type other than 1015).
      */
-    VENDOR1_PRIMARY,
-    VENDOR2_PRIMARY,
-    VENDOR3_PRIMARY,
-    VENDOR4_PRIMARY,
+    VENDOR_PRIMARY_START = ProgramType:VENDOR_START,
+    VENDOR_PRIMARY_END = ProgramType:VENDOR_END,
 };
 
 /**
@@ -276,14 +296,10 @@
     bitfield<ProgramInfoFlags> flags;
 
     /**
-     * Opaque vendor-specific string, to be passed to front-end without changes.
-     * Format of this string can vary across vendors.
+     * Vendor-specific information.
      *
-     * It may be used for extra features, that's not supported by a platform,
-     * for example: "paid-service=true;bitrate=320kbps".
-     *
-     * Front-end application MUST verify vendor/product name from the
-     * @1.0::Properties struct before doing any interpretation of this value.
+     * It may be used for extra features, not supported by the platform,
+     * for example: paid-service=true; bitrate=320kbps.
      */
-    string vendorInfo;
+    vec<VendorKeyValue> vendorInfo;
 };
diff --git a/broadcastradio/1.1/utils/OWNERS b/broadcastradio/1.1/utils/OWNERS
new file mode 100644
index 0000000..0c27b71
--- /dev/null
+++ b/broadcastradio/1.1/utils/OWNERS
@@ -0,0 +1,4 @@
+# Automotive team
+egranata@google.com
+keunyoung@google.com
+twasilczyk@google.com
diff --git a/broadcastradio/1.1/utils/Utils.cpp b/broadcastradio/1.1/utils/Utils.cpp
index 8bb7691..8ccd98e 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;
@@ -91,11 +93,7 @@
                 return haveEqualIds(a, b, IdentifierType::SXM_SERVICE_ID);
             }
             return haveEqualIds(a, b, IdentifierType::SXM_CHANNEL);
-        case ProgramType::VENDOR1:
-        case ProgramType::VENDOR2:
-        case ProgramType::VENDOR3:
-        case ProgramType::VENDOR4:
-        default:
+        default:  // includes all vendor types
             ALOGW("Unsupported program type: %s", toString(type).c_str());
             return false;
     }
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/broadcastradio/1.1/vts/OWNERS b/broadcastradio/1.1/vts/OWNERS
new file mode 100644
index 0000000..aa5ce82
--- /dev/null
+++ b/broadcastradio/1.1/vts/OWNERS
@@ -0,0 +1,8 @@
+# Automotive team
+egranata@google.com
+keunyoung@google.com
+twasilczyk@google.com
+
+# VTS team
+ryanjcampbell@google.com
+yim@google.com
diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
index c6bc344..a46378e 100644
--- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
+++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
@@ -62,8 +62,13 @@
 static constexpr auto kConfigTimeout = 10s;
 static constexpr auto kConnectModuleTimeout = 1s;
 static constexpr auto kTuneTimeout = 30s;
+static constexpr auto kEventPropagationTimeout = 1s;
 static constexpr auto kFullScanTimeout = 1min;
 
+static constexpr ProgramType kStandardProgramTypes[] = {
+    ProgramType::AM,  ProgramType::FM,   ProgramType::AM_HD, ProgramType::FM_HD,
+    ProgramType::DAB, ProgramType::DRMO, ProgramType::SXM};
+
 static void printSkipped(std::string msg) {
     std::cout << "[  SKIPPED ] " << msg << std::endl;
 }
@@ -76,7 +81,6 @@
     MOCK_METHOD2(tuneComplete, Return<void>(Result, const V1_0::ProgramInfo&));
     MOCK_TIMEOUT_METHOD2(tuneComplete_1_1, Return<void>(Result, const ProgramSelector&));
     MOCK_METHOD1(afSwitch, Return<void>(const V1_0::ProgramInfo&));
-    MOCK_METHOD1(afSwitch_1_1, Return<void>(const ProgramSelector&));
     MOCK_METHOD1(antennaStateChange, Return<void>(bool connected));
     MOCK_METHOD1(trafficAnnouncement, Return<void>(bool active));
     MOCK_METHOD1(emergencyAnnouncement, Return<void>(bool active));
@@ -84,7 +88,7 @@
     MOCK_METHOD1(backgroundScanAvailable, Return<void>(bool));
     MOCK_TIMEOUT_METHOD1(backgroundScanComplete, Return<void>(ProgramListResult));
     MOCK_METHOD0(programListChanged, Return<void>());
-    MOCK_METHOD0(programInfoChanged, Return<void>());
+    MOCK_TIMEOUT_METHOD1(currentProgramInfoChanged, Return<void>(const ProgramInfo&));
 };
 
 class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase,
@@ -265,7 +269,7 @@
     // first try...
     EXPECT_TIMEOUT_CALL(*mCallback, backgroundScanComplete, ProgramListResult::OK)
         .Times(AnyNumber());
-    auto hidlResult = mTuner->getProgramList("", getListCb);
+    auto hidlResult = mTuner->getProgramList({}, getListCb);
     EXPECT_TRUE(hidlResult.isOk());
     if (!hidlResult.isOk()) return false;
 
@@ -278,7 +282,7 @@
         EXPECT_TIMEOUT_CALL_WAIT(*mCallback, backgroundScanComplete, kFullScanTimeout);
 
         // second (last) try...
-        hidlResult = mTuner->getProgramList("", getListCb);
+        hidlResult = mTuner->getProgramList({}, getListCb);
         EXPECT_TRUE(hidlResult.isOk());
         if (!hidlResult.isOk()) return false;
         EXPECT_EQ(ProgramListResult::OK, getListResult);
@@ -315,7 +319,8 @@
  *  - getProgramList either succeeds or returns NOT_STARTED/NOT_READY status;
  *  - if the program list is NOT_STARTED, startBackgroundScan makes it completed
  *    within a full scan timeout and the next getProgramList call succeeds;
- *  - if the program list is not empty, tune_1_1 call succeeds.
+ *  - if the program list is not empty, tuneByProgramSelector call succeeds;
+ *  - getProgramInformation_1_1 returns the same selector as returned in tuneComplete_1_1 call.
  */
 TEST_P(BroadcastRadioHalTest, TuneFromProgramList) {
     if (skipped) return;
@@ -336,16 +341,74 @@
         return;
     }
 
+    ProgramInfo infoCb;
     ProgramSelector selCb;
     EXPECT_CALL(*mCallback, tuneComplete(_, _)).Times(0);
     EXPECT_TIMEOUT_CALL(*mCallback, tuneComplete_1_1, Result::OK, _)
         .WillOnce(DoAll(SaveArg<1>(&selCb), testing::Return(ByMove(Void()))));
-    auto tuneResult = mTuner->tune_1_1(firstProgram.selector);
+    EXPECT_TIMEOUT_CALL(*mCallback, currentProgramInfoChanged, _)
+        .WillOnce(DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(Void()))));
+    auto tuneResult = mTuner->tuneByProgramSelector(firstProgram.selector);
     ASSERT_EQ(Result::OK, tuneResult);
     EXPECT_TIMEOUT_CALL_WAIT(*mCallback, tuneComplete_1_1, kTuneTimeout);
+    EXPECT_TIMEOUT_CALL_WAIT(*mCallback, currentProgramInfoChanged, kEventPropagationTimeout);
     EXPECT_EQ(firstProgram.selector.primaryId, selCb.primaryId);
+    EXPECT_EQ(infoCb.selector, selCb);
+
+    bool called = false;
+    auto getResult = mTuner->getProgramInformation_1_1([&](Result result, ProgramInfo info) {
+        called = true;
+        EXPECT_EQ(Result::OK, result);
+        EXPECT_EQ(selCb, info.selector);
+    });
+    ASSERT_TRUE(getResult.isOk());
+    ASSERT_TRUE(called);
 }
 
+/**
+ * Test that primary vendor identifier isn't used for standard program types.
+ *
+ * Verifies that:
+ *  - tuneByProgramSelector fails when VENDORn_PRIMARY is set as a primary
+ *    identifier for program types other than VENDORn.
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsForPrimaryVendor) {
+    if (skipped) return;
+    ASSERT_TRUE(openTuner());
+
+    for (auto ptype : kStandardProgramTypes) {
+        ALOGD("Checking %s...", toString(ptype).c_str());
+        ProgramSelector sel = {};
+        sel.programType = static_cast<uint32_t>(ptype);
+        sel.primaryId.type = static_cast<uint32_t>(IdentifierType::VENDOR_PRIMARY_START);
+
+        auto tuneResult = mTuner->tuneByProgramSelector(sel);
+        ASSERT_NE(Result::OK, tuneResult);
+    }
+}
+
+/**
+ * Test that tune with unknown program type fails.
+ *
+ * Verifies that:
+ *  - tuneByProgramSelector fails with INVALID_ARGUMENT when unknown program type is passed.
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsForUnknownProgram) {
+    if (skipped) return;
+    ASSERT_TRUE(openTuner());
+
+    // Program type is 1-based, so 0 will be always invalid.
+    ProgramSelector sel = {};
+    auto tuneResult = mTuner->tuneByProgramSelector(sel);
+    ASSERT_EQ(Result::INVALID_ARGUMENTS, tuneResult);
+}
+
+/**
+ * Test cancelling announcement.
+ *
+ * Verifies that:
+ *  - cancelAnnouncement succeeds either when there is an announcement or there is none.
+ */
 TEST_P(BroadcastRadioHalTest, CancelAnnouncement) {
     if (skipped) return;
     ASSERT_TRUE(openTuner());
@@ -358,7 +421,7 @@
  * Test getImage call with invalid image ID.
  *
  * Verifies that:
- * - getImage call handles argument 0 gracefully
+ * - getImage call handles argument 0 gracefully.
  */
 TEST_P(BroadcastRadioHalTest, GetNoImage) {
     if (skipped) return;
@@ -375,8 +438,8 @@
  * Test proper image format in metadata.
  *
  * Verifies that:
- * - all images in metadata are provided out-of-band (by id, not as a binary blob)
- * - images are available for getImage call
+ * - all images in metadata are provided out-of-band (by id, not as a binary blob);
+ * - images are available for getImage call.
  */
 TEST_P(BroadcastRadioHalTest, OobImagesOnly) {
     if (skipped) return;
@@ -416,6 +479,52 @@
     }
 }
 
+/**
+ * Test AnalogForced switch.
+ *
+ * Verifies that:
+ * - setAnalogForced results either with INVALID_STATE, or isAnalogForced replying the same.
+ */
+TEST_P(BroadcastRadioHalTest, AnalogForcedSwitch) {
+    if (skipped) return;
+    ASSERT_TRUE(openTuner());
+
+    bool forced;
+    Result halIsResult;
+    auto isCb = [&](Result result, bool isForced) {
+        halIsResult = result;
+        forced = isForced;
+    };
+
+    // set analog mode
+    auto setResult = mTuner->setAnalogForced(true);
+    ASSERT_TRUE(setResult.isOk());
+    if (Result::INVALID_STATE == setResult) {
+        // if setter fails, getter should fail too - it means the switch is not supported at all
+        auto isResult = mTuner->isAnalogForced(isCb);
+        ASSERT_TRUE(isResult.isOk());
+        EXPECT_EQ(Result::INVALID_STATE, halIsResult);
+        return;
+    }
+    ASSERT_EQ(Result::OK, setResult);
+
+    // check, if it's analog
+    auto isResult = mTuner->isAnalogForced(isCb);
+    ASSERT_TRUE(isResult.isOk());
+    EXPECT_EQ(Result::OK, halIsResult);
+    ASSERT_TRUE(forced);
+
+    // set digital mode
+    setResult = mTuner->setAnalogForced(false);
+    ASSERT_EQ(Result::OK, setResult);
+
+    // check, if it's digital
+    isResult = mTuner->isAnalogForced(isCb);
+    ASSERT_TRUE(isResult.isOk());
+    EXPECT_EQ(Result::OK, halIsResult);
+    ASSERT_FALSE(forced);
+}
+
 INSTANTIATE_TEST_CASE_P(BroadcastRadioHalTestCases, BroadcastRadioHalTest,
                         ::testing::Values(Class::AM_FM, Class::SAT, Class::DT));
 
diff --git a/broadcastradio/1.1/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h b/broadcastradio/1.1/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h
index fa1114f..b0ce088 100644
--- a/broadcastradio/1.1/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h
+++ b/broadcastradio/1.1/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h
@@ -44,6 +44,14 @@
     return ret;
 
 /**
+ * Gmock MOCK_METHOD0 timeout-capable extension.
+ */
+#define MOCK_TIMEOUT_METHOD0(Method, ...)       \
+    MOCK_METHOD0(egmock_##Method, __VA_ARGS__); \
+    EGMOCK_TIMEOUT_METHOD_DEF_(Method);         \
+    virtual GMOCK_RESULT_(, __VA_ARGS__) Method() { EGMOCK_TIMEOUT_METHOD_BODY_(Method); }
+
+/**
  * Gmock MOCK_METHOD1 timeout-capable extension.
  */
 #define MOCK_TIMEOUT_METHOD1(Method, ...)                                                 \
diff --git a/camera/common/1.0/Android.bp b/camera/common/1.0/Android.bp
index 252d490..ade7260 100644
--- a/camera/common/1.0/Android.bp
+++ b/camera/common/1.0/Android.bp
@@ -32,13 +32,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.camera.common@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.camera.common@1.0_genc++"],
     generated_headers: ["android.hardware.camera.common@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.camera.common@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp
index 3ef40c8..b8335f9 100644
--- a/camera/device/1.0/Android.bp
+++ b/camera/device/1.0/Android.bp
@@ -53,13 +53,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.camera.device@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.camera.device@1.0_genc++"],
     generated_headers: ["android.hardware.camera.device@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.camera.device@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp
index dbc80ab..24c2151 100644
--- a/camera/device/3.2/Android.bp
+++ b/camera/device/3.2/Android.bp
@@ -53,13 +53,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.camera.device@3.2",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.camera.device@3.2_genc++"],
     generated_headers: ["android.hardware.camera.device@3.2_genc++_headers"],
     export_generated_headers: ["android.hardware.camera.device@3.2_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/camera/metadata/3.2/Android.bp b/camera/metadata/3.2/Android.bp
index 707b521..3c4b5e9 100644
--- a/camera/metadata/3.2/Android.bp
+++ b/camera/metadata/3.2/Android.bp
@@ -32,13 +32,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.camera.metadata@3.2",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.camera.metadata@3.2_genc++"],
     generated_headers: ["android.hardware.camera.metadata@3.2_genc++_headers"],
     export_generated_headers: ["android.hardware.camera.metadata@3.2_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 36a726a..82a3a78 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.camera.provider@2.4",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.camera.provider@2.4_genc++"],
     generated_headers: ["android.hardware.camera.provider@2.4_genc++_headers"],
     export_generated_headers: ["android.hardware.camera.provider@2.4_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
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/cas/1.0/Android.bp b/cas/1.0/Android.bp
index 2251f11..6d94793 100644
--- a/cas/1.0/Android.bp
+++ b/cas/1.0/Android.bp
@@ -60,13 +60,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.cas@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.cas@1.0_genc++"],
     generated_headers: ["android.hardware.cas@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.cas@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/cas/native/1.0/Android.bp b/cas/native/1.0/Android.bp
index 414fca7..e39cab1 100644
--- a/cas/native/1.0/Android.bp
+++ b/cas/native/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.cas.native@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.cas.native@1.0_genc++"],
     generated_headers: ["android.hardware.cas.native@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.cas.native@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/configstore/1.0/Android.bp b/configstore/1.0/Android.bp
index 89f99f2..96ef00a 100644
--- a/configstore/1.0/Android.bp
+++ b/configstore/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.configstore@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.configstore@1.0_genc++"],
     generated_headers: ["android.hardware.configstore@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.configstore@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp
index 2d8cb64..92fb7c1 100644
--- a/configstore/1.1/Android.bp
+++ b/configstore/1.1/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.configstore@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.configstore@1.1_genc++"],
     generated_headers: ["android.hardware.configstore@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.configstore@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/configstore/utils/Android.bp b/configstore/utils/Android.bp
index a4cad66..93e52f1 100644
--- a/configstore/utils/Android.bp
+++ b/configstore/utils/Android.bp
@@ -17,6 +17,9 @@
 cc_library_shared {
     name: "android.hardware.configstore-utils",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     defaults: ["hidl_defaults"],
 
     srcs: [ "ConfigStoreUtils.cpp" ],
diff --git a/contexthub/1.0/Android.bp b/contexthub/1.0/Android.bp
index 45d2e5c..ae1bd08 100644
--- a/contexthub/1.0/Android.bp
+++ b/contexthub/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.contexthub@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.contexthub@1.0_genc++"],
     generated_headers: ["android.hardware.contexthub@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.contexthub@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/current.txt b/current.txt
index 67f1169..bb5f2ac 100644
--- a/current.txt
+++ b/current.txt
@@ -190,8 +190,10 @@
 # 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
+6e69adb24d7c0b0ca3a54a38c49a5625b161b3f5d5f7d6fda0befdbbfc8e9e06 android.hardware.radio@1.0::IRadioResponse
 28e929b453df3d9f5060af2764e6cdb123ddb893e3e86923c877f6ff7e5f02c9 android.hardware.wifi@1.0::types
 
 # HALs released in Android O MR1
@@ -220,4 +222,4 @@
 c3354ab0d381a236c12dc486ad4b6bec28c979d26748b4661f12ede36f392808 android.hardware.wifi.offload@1.0::IOffloadCallback
 b18caefefcc765092412285d776234fcf213b73bdf07ae1b67a5f71b2d2464e3 android.hardware.wifi.offload@1.0::types
 c26473e2e4a00af43e28a0ddf9002e5062a7d0940429e5efb6e5513a8abcb75c android.hardware.wifi@1.1::IWifi
-bfcf4856c7b6c66ebc56785ed3e5d181b7be859c2add672497a843b024518737 android.hardware.wifi@1.1::IWifiChip
+b056e1defab4071584214584057d0bc73a613081bf1152590549649d4582c13c android.hardware.wifi@1.1::IWifiChip
diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp
index 731f58f..d004b82 100644
--- a/drm/1.0/Android.bp
+++ b/drm/1.0/Android.bp
@@ -67,13 +67,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.drm@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.drm@1.0_genc++"],
     generated_headers: ["android.hardware.drm@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.drm@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
@@ -89,5 +92,3 @@
         "libutils",
     ],
 }
-
-subdirs = ["default"]
diff --git a/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp b/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
index eeee3c0..5564513 100644
--- a/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_clearkey_test.cpp
@@ -1064,8 +1064,6 @@
     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
 
     size_t offset = 0;
-    size_t num = 0;
-    size_t ecount_buf = 0;
     for (size_t i = 0; i < subSamples.size(); i++) {
         memcpy(dest + offset, src + offset, subSamples[i].numBytesOfClearData);
         offset += subSamples[i].numBytesOfClearData;
@@ -1106,7 +1104,6 @@
     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
     EXPECT_EQ(Status::OK, status);
 
-    const bool kNotSecure = false;
     uint32_t byteCount = decrypt(Mode::UNENCRYPTED, &iv[0], subSamples,
             noPattern, Status::OK);
     EXPECT_EQ(kByteCount, byteCount);
@@ -1133,7 +1130,6 @@
     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
     EXPECT_EQ(Status::OK, status);
 
-    const bool kNotSecure = false;
     uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
             noPattern, Status::OK);
     EXPECT_EQ(kClearBytes + kEncryptedBytes, byteCount);
@@ -1154,7 +1150,6 @@
     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
     EXPECT_EQ(Status::OK, status);
 
-    const bool kNotSecure = false;
     uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
             noPattern, Status::ERROR_DRM_NO_LICENSE);
     EXPECT_EQ(0u, byteCount);
diff --git a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
index 6ce465f..61f3014 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -1406,8 +1406,6 @@
     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
 
     size_t offset = 0;
-    size_t num = 0;
-    size_t ecount_buf = 0;
     for (size_t i = 0; i < subSamples.size(); i++) {
         const SubSample& subSample = subSamples[i];
 
diff --git a/drm/Android.bp b/drm/Android.bp
index 33f70eb..ed19a37 100644
--- a/drm/Android.bp
+++ b/drm/Android.bp
@@ -1,5 +1,6 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/default",
     "1.0/vts/functional",
 ]
diff --git a/dumpstate/1.0/Android.bp b/dumpstate/1.0/Android.bp
index 2424c33..b135e00 100644
--- a/dumpstate/1.0/Android.bp
+++ b/dumpstate/1.0/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.dumpstate@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.dumpstate@1.0_genc++"],
     generated_headers: ["android.hardware.dumpstate@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.dumpstate@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/gatekeeper/1.0/Android.bp b/gatekeeper/1.0/Android.bp
index eb70c09..f12f38f 100644
--- a/gatekeeper/1.0/Android.bp
+++ b/gatekeeper/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.gatekeeper@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.gatekeeper@1.0_genc++"],
     generated_headers: ["android.hardware.gatekeeper@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.gatekeeper@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/gnss/1.0/Android.bp b/gnss/1.0/Android.bp
index c2988de..6db98f6 100644
--- a/gnss/1.0/Android.bp
+++ b/gnss/1.0/Android.bp
@@ -172,13 +172,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.gnss@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.gnss@1.0_genc++"],
     generated_headers: ["android.hardware.gnss@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.gnss@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
index 2c2a3da..46faa17 100644
--- a/graphics/allocator/2.0/Android.bp
+++ b/graphics/allocator/2.0/Android.bp
@@ -35,13 +35,17 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.graphics.allocator@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.graphics.allocator@2.0_genc++"],
     generated_headers: ["android.hardware.graphics.allocator@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.graphics.allocator@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp
index 4773963..2d36fc7 100644
--- a/graphics/bufferqueue/1.0/Android.bp
+++ b/graphics/bufferqueue/1.0/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.graphics.bufferqueue@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.graphics.bufferqueue@1.0_genc++"],
     generated_headers: ["android.hardware.graphics.bufferqueue@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.graphics.bufferqueue@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/graphics/common/1.0/Android.bp b/graphics/common/1.0/Android.bp
index 3d9aa90..86438c1 100644
--- a/graphics/common/1.0/Android.bp
+++ b/graphics/common/1.0/Android.bp
@@ -32,13 +32,17 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.graphics.common@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.graphics.common@1.0_genc++"],
     generated_headers: ["android.hardware.graphics.common@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.graphics.common@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/graphics/composer/2.1/Android.bp b/graphics/composer/2.1/Android.bp
index 299570d..e875708 100644
--- a/graphics/composer/2.1/Android.bp
+++ b/graphics/composer/2.1/Android.bp
@@ -53,13 +53,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.graphics.composer@2.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.graphics.composer@2.1_genc++"],
     generated_headers: ["android.hardware.graphics.composer@2.1_genc++_headers"],
     export_generated_headers: ["android.hardware.graphics.composer@2.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index 8ca0eb3..862dff1 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -18,6 +18,7 @@
 
 #include "Hwc.h"
 
+#include <chrono>
 #include <type_traits>
 #include <log/log.h>
 
@@ -25,6 +26,8 @@
 #include "hardware/hwcomposer.h"
 #include "hwc2on1adapter/HWC2On1Adapter.h"
 
+using namespace std::chrono_literals;
+
 namespace android {
 namespace hardware {
 namespace graphics {
@@ -218,7 +221,24 @@
     sp<ComposerClient> client;
 
     {
-        std::lock_guard<std::mutex> lock(mClientMutex);
+        std::unique_lock<std::mutex> lock(mClientMutex);
+
+        if (mClient != nullptr) {
+            // In surface flinger we delete a composer client on one thread and
+            // then create a new client on another thread. Although surface
+            // flinger ensures the calls are made in that sequence (destroy and
+            // then create), sometimes the calls land in the composer service
+            // inverted (create and then destroy). Wait for a brief period to
+            // see if the existing client is destroyed.
+            ALOGI("HwcHal::createClient: Client already exists. Waiting for"
+                    " it to be destroyed.");
+            mClientDestroyedWait.wait_for(lock, 1s,
+                    [this] { return mClient == nullptr; });
+            std::string doneMsg = mClient == nullptr ?
+                    "Existing client was destroyed." :
+                    "Existing client was never destroyed!";
+            ALOGI("HwcHal::createClient: Done waiting. %s", doneMsg.c_str());
+        }
 
         // only one client is allowed
         if (mClient == nullptr) {
@@ -245,6 +265,7 @@
 {
     std::lock_guard<std::mutex> lock(mClientMutex);
     mClient = nullptr;
+    mClientDestroyedWait.notify_all();
 }
 
 void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
index b45389a..7561327 100644
--- a/graphics/composer/2.1/default/Hwc.h
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -17,8 +17,9 @@
 #ifndef ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
 #define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
 
-#include <mutex>
+#include <condition_variable>
 #include <memory>
+#include <mutex>
 #include <unordered_set>
 #include <vector>
 
@@ -211,6 +212,7 @@
     } mDispatch;
 
     std::mutex mClientMutex;
+    std::condition_variable mClientDestroyedWait;
     wp<ComposerClient> mClient;
 
     // If the HWC implementation version is < 2.0, use an adapter to interface
diff --git a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
index ada7d09..e332086 100644
--- a/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
+++ b/graphics/composer/2.1/vts/functional/GraphicsComposerCallback.h
@@ -51,7 +51,7 @@
   // the set of all currently connected displays
   std::unordered_set<Display> mDisplays;
   // true only when vsync is enabled
-  bool mVsyncAllowed = false;
+  bool mVsyncAllowed = true;
 
   // track invalid callbacks
   int mInvalidHotplugCount = 0;
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
index 4e65a95..c66cdd0 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerTestUtils.cpp
@@ -297,6 +297,11 @@
                                            : IComposerClient::Vsync::DISABLE;
   Error error = mClient->setVsyncEnabled(display, vsync);
   ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
+
+  // give the hwbinder thread some time to handle any pending vsync callback
+  if (!enabled) {
+      usleep(5 * 1000);
+  }
 }
 
 void ComposerClient::execute(TestCommandReader* reader,
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index c77b7d3..0f03546 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -61,6 +61,10 @@
 
     // assume the first display is primary and is never removed
     mPrimaryDisplay = waitForFirstDisplay();
+
+    // explicitly disable vsync
+    mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
+    mComposerCallback->setVsyncAllowed(false);
   }
 
   void TearDown() override {
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 408d58f..f5913af 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -39,13 +39,17 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.graphics.mapper@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.graphics.mapper@2.0_genc++"],
     generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/health/1.0/Android.bp b/health/1.0/Android.bp
index 4fb2d7b..d8ebc20 100644
--- a/health/1.0/Android.bp
+++ b/health/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.health@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.health@1.0_genc++"],
     generated_headers: ["android.hardware.health@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.health@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp
index c57152f..cb2e87d 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -1,7 +1,3 @@
-subdirs = [
-    "libhealthd",
-]
-
 cc_library_static {
     name: "android.hardware.health@1.0-convert",
     vendor_available: true,
diff --git a/health/Android.bp b/health/Android.bp
index ed19a37..a6f6017 100644
--- a/health/Android.bp
+++ b/health/Android.bp
@@ -2,5 +2,6 @@
 subdirs = [
     "1.0",
     "1.0/default",
+    "1.0/default/libhealthd",
     "1.0/vts/functional",
 ]
diff --git a/ir/1.0/Android.bp b/ir/1.0/Android.bp
index a059da5..489f61f 100644
--- a/ir/1.0/Android.bp
+++ b/ir/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.ir@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.ir@1.0_genc++"],
     generated_headers: ["android.hardware.ir@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.ir@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/ir/1.0/vts/functional/Android.bp b/ir/1.0/vts/functional/Android.bp
index 4aac297..2a86f8e 100644
--- a/ir/1.0/vts/functional/Android.bp
+++ b/ir/1.0/vts/functional/Android.bp
@@ -16,20 +16,9 @@
 
 cc_test {
     name: "VtsHalIrV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalIrV1_0TargetTest.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libutils",
+    static_libs: [
         "android.hardware.ir@1.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
-    ],
 }
diff --git a/keymaster/3.0/Android.bp b/keymaster/3.0/Android.bp
index 1846200..14cfab2 100644
--- a/keymaster/3.0/Android.bp
+++ b/keymaster/3.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.keymaster@3.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.keymaster@3.0_genc++"],
     generated_headers: ["android.hardware.keymaster@3.0_genc++_headers"],
     export_generated_headers: ["android.hardware.keymaster@3.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp
index cffdbe0..7cc7f84 100644
--- a/light/2.0/Android.bp
+++ b/light/2.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.light@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.light@2.0_genc++"],
     generated_headers: ["android.hardware.light@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.light@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/media/1.0/Android.bp b/media/1.0/Android.bp
index 61eeb3f..de2187e 100644
--- a/media/1.0/Android.bp
+++ b/media/1.0/Android.bp
@@ -32,13 +32,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.media@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.media@1.0_genc++"],
     generated_headers: ["android.hardware.media@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.media@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
index 8e5527e..f8bed6e 100644
--- a/media/omx/1.0/Android.bp
+++ b/media/omx/1.0/Android.bp
@@ -74,13 +74,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.media.omx@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.media.omx@1.0_genc++"],
     generated_headers: ["android.hardware.media.omx@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.media.omx@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/memtrack/1.0/Android.bp b/memtrack/1.0/Android.bp
index 6f6e16d..4df2c1d 100644
--- a/memtrack/1.0/Android.bp
+++ b/memtrack/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.memtrack@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.memtrack@1.0_genc++"],
     generated_headers: ["android.hardware.memtrack@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.memtrack@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/neuralnetworks/1.0/Android.bp b/neuralnetworks/1.0/Android.bp
new file mode 100644
index 0000000..b5603a2
--- /dev/null
+++ b/neuralnetworks/1.0/Android.bp
@@ -0,0 +1,73 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.neuralnetworks@1.0_hal",
+    srcs: [
+        "types.hal",
+        "IDevice.hal",
+        "IPreparedModel.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.neuralnetworks@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.neuralnetworks@1.0",
+    srcs: [
+        ":android.hardware.neuralnetworks@1.0_hal",
+    ],
+    out: [
+        "android/hardware/neuralnetworks/1.0/types.cpp",
+        "android/hardware/neuralnetworks/1.0/DeviceAll.cpp",
+        "android/hardware/neuralnetworks/1.0/PreparedModelAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.neuralnetworks@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.neuralnetworks@1.0",
+    srcs: [
+        ":android.hardware.neuralnetworks@1.0_hal",
+    ],
+    out: [
+        "android/hardware/neuralnetworks/1.0/types.h",
+        "android/hardware/neuralnetworks/1.0/hwtypes.h",
+        "android/hardware/neuralnetworks/1.0/IDevice.h",
+        "android/hardware/neuralnetworks/1.0/IHwDevice.h",
+        "android/hardware/neuralnetworks/1.0/BnHwDevice.h",
+        "android/hardware/neuralnetworks/1.0/BpHwDevice.h",
+        "android/hardware/neuralnetworks/1.0/BsDevice.h",
+        "android/hardware/neuralnetworks/1.0/IPreparedModel.h",
+        "android/hardware/neuralnetworks/1.0/IHwPreparedModel.h",
+        "android/hardware/neuralnetworks/1.0/BnHwPreparedModel.h",
+        "android/hardware/neuralnetworks/1.0/BpHwPreparedModel.h",
+        "android/hardware/neuralnetworks/1.0/BsPreparedModel.h",
+    ],
+}
+
+cc_library {
+    name: "android.hardware.neuralnetworks@1.0",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.neuralnetworks@1.0_genc++"],
+    generated_headers: ["android.hardware.neuralnetworks@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.neuralnetworks@1.0_genc++_headers"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+    ],
+}
diff --git a/neuralnetworks/1.0/IDevice.hal b/neuralnetworks/1.0/IDevice.hal
new file mode 100644
index 0000000..b826b23
--- /dev/null
+++ b/neuralnetworks/1.0/IDevice.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This HAL is a work in progress */
+
+package android.hardware.neuralnetworks@1.0;
+
+import IPreparedModel;
+
+interface IDevice {
+    initialize() generates(Capabilities capabilities);
+
+    getSupportedSubgraph(Model model) generates(vec<bool> supported);
+
+    prepareModel(Model model) generates(IPreparedModel preparedModel);
+
+    getStatus() generates(DeviceStatus status);
+};
diff --git a/neuralnetworks/1.0/IPreparedModel.hal b/neuralnetworks/1.0/IPreparedModel.hal
new file mode 100644
index 0000000..566d6ac
--- /dev/null
+++ b/neuralnetworks/1.0/IPreparedModel.hal
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This HAL is a work in progress */
+
+package android.hardware.neuralnetworks@1.0;
+
+interface IPreparedModel {
+    // TODO: The execution is synchronous.  Change that to have a callback on completion.
+    // Multiple threads can call this execute function concurrently.
+    execute(Request request) generates(bool success);
+};
diff --git a/neuralnetworks/1.0/types.hal b/neuralnetworks/1.0/types.hal
new file mode 100644
index 0000000..ccc17f1
--- /dev/null
+++ b/neuralnetworks/1.0/types.hal
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This HAL is a work in progress */
+
+package android.hardware.neuralnetworks@1.0;
+
+// The types an operand can have.
+// These values are the same as found in the NeuralNetworks.h file.
+// When modifying, be sure to update HAL_NUM_OPERAND_TYPES in HalIntefaces.h.
+enum OperandType : uint32_t {
+    FLOAT16                   = 0,
+    FLOAT32                   = 1,
+    INT8                      = 2,
+    UINT8                     = 3,
+    INT16                     = 4,
+    UINT16                    = 5,
+    INT32                     = 6,
+    UINT32                    = 7,
+    TENSOR_FLOAT16            = 8,
+    TENSOR_FLOAT32            = 9,
+    TENSOR_SYMMETRICAL_QUANT8 = 10,
+};
+
+// The type of operations.  Unlike the operation types found in
+// NeuralNetworks.h file, these specify the data type they operate on.
+// This is done to simplify the work of drivers.
+// TODO: Currently they are the same.  Add a conversion when finalizing the model.
+// When modifying, be sure to update HAL_NUM_OPERATION_TYPES in HalIntefaces.h.
+enum OperationType : uint32_t {
+    AVERAGE_POOL_FLOAT32                 = 0,
+    CONCATENATION_FLOAT32                = 1,
+    CONV_FLOAT32                         = 2,
+    DEPTHWISE_CONV_FLOAT32               = 3,
+    MAX_POOL_FLOAT32                     = 4,
+    L2_POOL_FLOAT32                      = 5,
+    DEPTH_TO_SPACE_FLOAT32               = 6,
+    SPACE_TO_DEPTH_FLOAT32               = 7,
+    LOCAL_RESPONSE_NORMALIZATION_FLOAT32 = 8,
+    SOFTMAX_FLOAT32                      = 9,
+    RESHAPE_FLOAT32                      = 10,
+    SPLIT_FLOAT32                        = 11,
+    FAKE_QUANT_FLOAT32                   = 12,
+    ADD_FLOAT32                          = 13,
+    FULLY_CONNECTED_FLOAT32              = 14,
+    CAST_FLOAT32                         = 15,
+    MUL_FLOAT32                          = 16,
+    L2_NORMALIZATION_FLOAT32             = 17,
+    LOGISTIC_FLOAT32                     = 18,
+    RELU_FLOAT32                         = 19,
+    RELU6_FLOAT32                        = 20,
+    RELU1_FLOAT32                        = 21,
+    TANH_FLOAT32                         = 22,
+    DEQUANTIZE_FLOAT32                   = 23,
+    FLOOR_FLOAT32                        = 24,
+    GATHER_FLOAT32                       = 25,
+    RESIZE_BILINEAR_FLOAT32              = 26,
+    LSH_PROJECTION_FLOAT32               = 27,
+    LSTM_FLOAT32                         = 28,
+    SVDF_FLOAT32                         = 29,
+    RNN_FLOAT32                          = 30,
+    N_GRAM_FLOAT32                       = 31,
+    LOOKUP_FLOAT32                       = 32,
+};
+
+// Two special values that can be used instead of a regular poolIndex.
+enum LocationValues : uint32_t {
+    // The location will be specified at runtime. It's either a temporary
+    // variable, an input, or an output.
+    LOCATION_AT_RUN_TIME = 0xFFFFFFFF,
+    // The operand's value is stored in the
+    // TODO: Only for old
+    LOCATION_SAME_BLOCK = 0xFFFFFFFE
+};
+
+// Status of a device.
+enum DeviceStatus : uint32_t {
+    AVAILABLE,
+    BUSY,
+    OFFLINE,
+    UNKNOWN  // Do we need this?
+};
+
+// For the reference workload
+// Used by a driver to report its performance characteristics.
+// TODO revisit the data types and scales.
+struct PerformanceInfo {
+    float execTime;    // in nanoseconds
+    float powerUsage;  // in picoJoules
+};
+
+// The capabilities of a driver.
+struct Capabilities {
+    vec<OperationType> supportedOperationTypes;
+    // TODO Do the same for baseline model IDs
+    bool cachesCompilation;
+    // TODO revisit the data types and scales.
+    float bootupTime;  // in nanoseconds
+    PerformanceInfo float16Performance;
+    PerformanceInfo float32Performance;
+    PerformanceInfo quantized8Performance;
+};
+
+// Describes the location of a data object.
+struct DataLocation {
+    // The index of the memory pool where this location is found.
+    // Two special values can also be used.  See the LOCATION_* constants above.
+    uint32_t poolIndex;
+    // Offset in bytes from the start of the pool.
+    uint32_t offset;
+    // The length of the data, in bytes.
+    uint32_t length;
+};
+
+struct Operand {
+    OperandType type;
+    vec<uint32_t> dimensions;
+
+    // The number of operations that uses this operand as input.
+    // TODO It would be nice to track the actual consumers, e.g. vec<uint32_t> consumers;
+    uint32_t numberOfConsumers;
+
+    float scale;
+    int32_t zeroPoint;
+
+    // Where to find the data for this operand.
+    DataLocation location;
+};
+
+// Describes one operation of the graph.
+struct Operation {
+    // The type of operation.
+    OperationType type;
+    // Describes the table that contains the indexes of the inputs of the
+    // operation. The offset is the index in the operandIndexes table.
+    vec<uint32_t> inputs;
+    // Describes the table that contains the indexes of the outputs of the
+    // operation. The offset is the index in the operandIndexes table.
+    vec<uint32_t> outputs;
+};
+
+struct InputOutputInfo {
+    DataLocation location;
+    // If dimensions.size() > 0, we have updated dimensions.
+    vec<uint32_t> dimensions;
+};
+
+struct Model {
+    vec<Operand> operands;
+    vec<Operation> operations;
+    vec<uint32_t> inputIndexes;
+    vec<uint32_t> outputIndexes;
+    vec<uint8_t> operandValues;
+    vec<memory> pools;
+};
+
+struct Request {
+    vec<InputOutputInfo> inputs;
+    vec<InputOutputInfo> outputs;
+    vec<memory> pools;
+};
diff --git a/neuralnetworks/1.0/vts/OWNERS b/neuralnetworks/1.0/vts/OWNERS
new file mode 100644
index 0000000..59e7c28
--- /dev/null
+++ b/neuralnetworks/1.0/vts/OWNERS
@@ -0,0 +1,11 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+ijsung@google.com
+jeanluc@google.com
+miaowang@google.com
+yangni@google.com
+
+# VTS team
+yim@google.com
+yuexima@google.com
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..96eb4cb
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalNeuralnetworksV1_0TargetTest",
+    srcs: ["VtsHalNeuralnetworksV1_0TargetTest.cpp"],
+    defaults: ["hidl_defaults"],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.neuralnetworks@1.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
new file mode 100644
index 0000000..9fa694d
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworksV1_0TargetTest.h"
+#include <android-base/logging.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+#include <string>
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace vts {
+namespace functional {
+
+// A class for test environment setup
+NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
+
+NeuralnetworksHidlEnvironment* NeuralnetworksHidlEnvironment::getInstance() {
+    // This has to return a "new" object because it is freed inside
+    // ::testing::AddGlobalTestEnvironment when the gtest is being torn down
+    static NeuralnetworksHidlEnvironment* instance = new NeuralnetworksHidlEnvironment();
+    return instance;
+}
+
+void NeuralnetworksHidlEnvironment::registerTestServices() {
+    registerTestService("android.hardware.neuralnetworks", "1.0", "IDevice");
+}
+
+// The main test class for NEURALNETWORK HIDL HAL.
+void NeuralnetworksHidlTest::SetUp() {
+    std::string instance =
+        NeuralnetworksHidlEnvironment::getInstance()->getServiceName(IDevice::descriptor);
+    LOG(INFO) << "running vts test with instance: " << instance;
+    device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(instance);
+    ASSERT_NE(nullptr, device.get());
+}
+
+void NeuralnetworksHidlTest::TearDown() {}
+
+// create device test
+TEST_F(NeuralnetworksHidlTest, CreateDevice) {}
+
+// status test
+TEST_F(NeuralnetworksHidlTest, StatusTest) {
+    DeviceStatus status = device->getStatus();
+    EXPECT_EQ(DeviceStatus::AVAILABLE, status);
+}
+
+// initialization
+TEST_F(NeuralnetworksHidlTest, InitializeTest) {
+    Return<void> ret = device->initialize([](const Capabilities& capabilities) {
+        EXPECT_NE(nullptr, capabilities.supportedOperationTypes.data());
+        EXPECT_NE(0ull, capabilities.supportedOperationTypes.size());
+        EXPECT_EQ(0u, static_cast<uint32_t>(capabilities.cachesCompilation) & ~0x1);
+        EXPECT_LT(0.0f, capabilities.bootupTime);
+        EXPECT_LT(0.0f, capabilities.float16Performance.execTime);
+        EXPECT_LT(0.0f, capabilities.float16Performance.powerUsage);
+        EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
+        EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
+        EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
+        EXPECT_LT(0.0f, capabilities.quantized8Performance.powerUsage);
+    });
+    EXPECT_TRUE(ret.isOk());
+}
+
+namespace {
+// create the model
+Model createTestModel() {
+    const std::vector<float> operand2Data = {5.0f, 6.0f, 7.0f, 8.0f};
+    const uint32_t size = operand2Data.size() * sizeof(float);
+
+    const uint32_t operand1 = 0;
+    const uint32_t operand2 = 1;
+    const uint32_t operand3 = 2;
+
+    const std::vector<Operand> operands = {
+        {
+            .type = OperandType::FLOAT32,
+            .dimensions = {1, 2, 2, 1},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_AT_RUN_TIME),
+                         .offset = 0,
+                         .length = 0},
+        },
+        {
+            .type = OperandType::FLOAT32,
+            .dimensions = {1, 2, 2, 1},
+            .numberOfConsumers = 1,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_SAME_BLOCK),
+                         .offset = 0,
+                         .length = size},
+        },
+        {
+            .type = OperandType::FLOAT32,
+            .dimensions = {1, 2, 2, 1},
+            .numberOfConsumers = 0,
+            .scale = 0.0f,
+            .zeroPoint = 0,
+            .location = {.poolIndex = static_cast<uint32_t>(LocationValues::LOCATION_AT_RUN_TIME),
+                         .offset = 0,
+                         .length = 0},
+        },
+    };
+
+    const std::vector<Operation> operations = {{
+        .type = OperationType::ADD_FLOAT32, .inputs = {operand1, operand2}, .outputs = {operand3},
+    }};
+
+    const std::vector<uint32_t> inputIndexes = {operand1};
+    const std::vector<uint32_t> outputIndexes = {operand3};
+    const std::vector<uint8_t> operandValues(reinterpret_cast<const uint8_t*>(operand2Data.data()),
+                                             reinterpret_cast<const uint8_t*>(operand2Data.data()) +
+                                                 operand2Data.size() * sizeof(float));
+    const std::vector<hidl_memory> pools = {};
+
+    return {
+        .operands = operands,
+        .operations = operations,
+        .inputIndexes = inputIndexes,
+        .outputIndexes = outputIndexes,
+        .operandValues = operandValues,
+        .pools = pools,
+    };
+}
+
+// allocator helper
+hidl_memory allocateSharedMemory(int64_t size, const std::string& type = "ashmem") {
+    hidl_memory memory;
+
+    sp<IAllocator> allocator = IAllocator::getService(type);
+    if (!allocator.get()) {
+        return {};
+    }
+
+    Return<void> ret = allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
+        ASSERT_TRUE(success);
+        memory = mem;
+    });
+    if (!ret.isOk()) {
+        return {};
+    }
+
+    return memory;
+}
+}  // anonymous namespace
+
+// supported subgraph test
+TEST_F(NeuralnetworksHidlTest, SupportedSubgraphTest) {
+    Model model = createTestModel();
+    std::vector<bool> supported;
+    Return<void> ret = device->getSupportedSubgraph(
+        model, [&](const hidl_vec<bool>& hidl_supported) { supported = hidl_supported; });
+    ASSERT_TRUE(ret.isOk());
+    EXPECT_EQ(/*model.operations.size()*/ 0ull, supported.size());
+}
+
+// execute simple graph
+TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphTest) {
+    std::vector<float> inputData = {1.0f, 2.0f, 3.0f, 4.0f};
+    std::vector<float> outputData = {-1.0f, -1.0f, -1.0f, -1.0f};
+    std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
+    const uint32_t INPUT = 0;
+    const uint32_t OUTPUT = 1;
+
+    // prpeare request
+    Model model = createTestModel();
+    sp<IPreparedModel> preparedModel = device->prepareModel(model);
+    ASSERT_NE(nullptr, preparedModel.get());
+
+    // prepare inputs
+    uint32_t inputSize = static_cast<uint32_t>(inputData.size() * sizeof(float));
+    uint32_t outputSize = static_cast<uint32_t>(outputData.size() * sizeof(float));
+    std::vector<InputOutputInfo> inputs = {{
+        .location = {.poolIndex = INPUT, .offset = 0, .length = inputSize}, .dimensions = {},
+    }};
+    std::vector<InputOutputInfo> outputs = {{
+        .location = {.poolIndex = OUTPUT, .offset = 0, .length = outputSize}, .dimensions = {},
+    }};
+    std::vector<hidl_memory> pools = {allocateSharedMemory(inputSize),
+                                      allocateSharedMemory(outputSize)};
+    ASSERT_NE(0ull, pools[INPUT].size());
+    ASSERT_NE(0ull, pools[OUTPUT].size());
+
+    // load data
+    sp<IMemory> inputMemory = mapMemory(pools[INPUT]);
+    sp<IMemory> outputMemory = mapMemory(pools[OUTPUT]);
+    ASSERT_NE(nullptr, inputMemory.get());
+    ASSERT_NE(nullptr, outputMemory.get());
+    float* inputPtr = reinterpret_cast<float*>(static_cast<void*>(inputMemory->getPointer()));
+    float* outputPtr = reinterpret_cast<float*>(static_cast<void*>(outputMemory->getPointer()));
+    ASSERT_NE(nullptr, inputPtr);
+    ASSERT_NE(nullptr, outputPtr);
+    std::copy(inputData.begin(), inputData.end(), inputPtr);
+    std::copy(outputData.begin(), outputData.end(), outputPtr);
+    inputMemory->commit();
+    outputMemory->commit();
+
+    // execute request
+    bool success = preparedModel->execute({.inputs = inputs, .outputs = outputs, .pools = pools});
+    EXPECT_TRUE(success);
+
+    // validate results { 1+5, 2+6, 3+7, 4+8 }
+    outputMemory->update();
+    std::copy(outputPtr, outputPtr + outputData.size(), outputData.begin());
+    EXPECT_EQ(expectedData, outputData);
+}
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_0
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+using android::hardware::neuralnetworks::V1_0::vts::functional::NeuralnetworksHidlEnvironment;
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(NeuralnetworksHidlEnvironment::getInstance());
+    ::testing::InitGoogleTest(&argc, argv);
+    NeuralnetworksHidlEnvironment::getInstance()->init(&argc, argv);
+
+    int status = RUN_ALL_TESTS();
+    return status;
+}
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
new file mode 100644
index 0000000..bb0cdaa
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
+#define VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
+
+#include <android/hardware/neuralnetworks/1.0/IDevice.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <string>
+
+using ::android::hardware::neuralnetworks::V1_0::IDevice;
+using ::android::hardware::neuralnetworks::V1_0::IPreparedModel;
+using ::android::hardware::neuralnetworks::V1_0::Capabilities;
+using ::android::hardware::neuralnetworks::V1_0::DeviceStatus;
+using ::android::hardware::neuralnetworks::V1_0::Model;
+using ::android::hardware::neuralnetworks::V1_0::OperationType;
+using ::android::hardware::neuralnetworks::V1_0::PerformanceInfo;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMemory;
+using ::android::sp;
+
+namespace android {
+namespace hardware {
+namespace neuralnetworks {
+namespace V1_0 {
+namespace vts {
+namespace functional {
+
+// A class for test environment setup
+class NeuralnetworksHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+    NeuralnetworksHidlEnvironment();
+    NeuralnetworksHidlEnvironment(const NeuralnetworksHidlEnvironment&) = delete;
+    NeuralnetworksHidlEnvironment(NeuralnetworksHidlEnvironment&&) = delete;
+    NeuralnetworksHidlEnvironment& operator=(const NeuralnetworksHidlEnvironment&) = delete;
+    NeuralnetworksHidlEnvironment& operator=(NeuralnetworksHidlEnvironment&&) = delete;
+
+   public:
+    static NeuralnetworksHidlEnvironment* getInstance();
+    virtual void registerTestServices() override;
+};
+
+// The main test class for NEURALNETWORKS HIDL HAL.
+class NeuralnetworksHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override;
+    virtual void TearDown() override;
+
+    sp<IDevice> device;
+};
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_0
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+#endif  // VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
diff --git a/neuralnetworks/Android.bp b/neuralnetworks/Android.bp
new file mode 100644
index 0000000..33f70eb
--- /dev/null
+++ b/neuralnetworks/Android.bp
@@ -0,0 +1,5 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+    "1.0/vts/functional",
+]
diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp
index 7c9a66e..4adb32c 100644
--- a/nfc/1.0/Android.bp
+++ b/nfc/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.nfc@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.nfc@1.0_genc++"],
     generated_headers: ["android.hardware.nfc@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.nfc@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/nfc/1.0/vts/functional/Android.bp b/nfc/1.0/vts/functional/Android.bp
index d9ba702..3861bd4 100644
--- a/nfc/1.0/vts/functional/Android.bp
+++ b/nfc/1.0/vts/functional/Android.bp
@@ -16,21 +16,9 @@
 
 cc_test {
     name: "VtsHalNfcV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalNfcV1_0TargetTest.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
+    static_libs: [
         "android.hardware.nfc@1.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
-    ],
 }
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index e67f94f..2f00fbb 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -44,6 +44,8 @@
   { 0x20, 0x04, 0x02, 0x01, 0x00 }
 #define CORE_INIT_CMD \
     { 0x20, 0x01, 0x00 }
+#define CORE_INIT_CMD_NCI20 \
+    { 0x20, 0x01, 0x02, 0x00, 0x00 }
 #define INVALID_COMMAND \
   { 0x20, 0x00, 0x00 }
 
@@ -290,16 +292,23 @@
         // Wait for CORE_RESET_NTF
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
         EXPECT_TRUE(res.no_timeout);
+        cmd = CORE_INIT_CMD_NCI20;
+    } else {
+        cmd = CORE_INIT_CMD;
     }
-
-    cmd = CORE_INIT_CMD;
     data = cmd;
+
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INIT_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
     EXPECT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
-
+    if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
+        res.args->last_data_[13] == 0x00) {
+        // Wait for CORE_CONN_CREDITS_NTF
+        res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+        EXPECT_TRUE(res.no_timeout);
+    }
     // Send an Error Data Packet
     cmd = INVALID_COMMAND;
     data = cmd;
@@ -347,15 +356,23 @@
         // Wait for CORE_RESET_NTF
         res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
         EXPECT_TRUE(res.no_timeout);
+        cmd = CORE_INIT_CMD_NCI20;
+    } else {
+        cmd = CORE_INIT_CMD;
     }
-
-    cmd = CORE_INIT_CMD;
     data = cmd;
+
     EXPECT_EQ(data.size(), nfc_->write(data));
     // Wait for CORE_INIT_RSP
     res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
     EXPECT_TRUE(res.no_timeout);
     EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
+    if (nci_version == NCI_VERSION_2 && res.args->last_data_.size() > 13 &&
+        res.args->last_data_[13] == 0x00) {
+        // Wait for CORE_CONN_CREDITS_NTF
+        res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
+        EXPECT_TRUE(res.no_timeout);
+    }
 
     cmd = CORE_CONN_CREATE_CMD;
     data = cmd;
diff --git a/oemlock/1.0/Android.bp b/oemlock/1.0/Android.bp
index 21e7271..742061d 100644
--- a/oemlock/1.0/Android.bp
+++ b/oemlock/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.oemlock@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.oemlock@1.0_genc++"],
     generated_headers: ["android.hardware.oemlock@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.oemlock@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/power/1.0/Android.bp b/power/1.0/Android.bp
index 1d967fd..bc886cb 100644
--- a/power/1.0/Android.bp
+++ b/power/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.power@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.power@1.0_genc++"],
     generated_headers: ["android.hardware.power@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.power@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/power/1.1/Android.bp b/power/1.1/Android.bp
index bfc140f..fb10aba 100644
--- a/power/1.1/Android.bp
+++ b/power/1.1/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.power@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.power@1.1_genc++"],
     generated_headers: ["android.hardware.power@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.power@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp
index 988f5d2..093ceac 100644
--- a/radio/1.0/Android.bp
+++ b/radio/1.0/Android.bp
@@ -67,13 +67,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.radio@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.radio@1.0_genc++"],
     generated_headers: ["android.hardware.radio@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.radio@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index a94aac3..94b304a 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -161,6 +161,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:SIM_ABSENT
      */
     oneway supplyNetworkDepersonalizationResponse(RadioResponseInfo info, int32_t remainingRetries);
 
@@ -544,6 +545,7 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway sendSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -574,6 +576,7 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway sendSMSExpectMoreResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -594,6 +597,7 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway setupDataCallResponse(RadioResponseInfo info, SetupDataCallResult dcResponse);
 
@@ -860,6 +864,7 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway deactivateDataCallResponse(RadioResponseInfo info);
 
@@ -1166,6 +1171,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:SIM_ABSENT
      */
     oneway getDataCallListResponse(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);
 
@@ -1210,6 +1216,7 @@
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:SIM_ABSENT
      */
     oneway writeSmsToSimResponse(RadioResponseInfo info, int32_t index);
 
@@ -1231,6 +1238,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:SIM_ABSENT
      */
     oneway deleteSmsOnSimResponse(RadioResponseInfo info);
 
@@ -1615,6 +1623,7 @@
      *   RadioError:ENCODING_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway sendCdmaSmsResponse(RadioResponseInfo info, SendSmsResult sms);
 
@@ -1819,6 +1828,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:SIM_ABSENT
      */
     oneway writeSmsToRuimResponse(RadioResponseInfo info, uint32_t index);
 
@@ -1839,6 +1849,8 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     *   RadioError:OPERATION_NOT_ALLOWED
+     *   RadioError:SIM_ABSENT
      */
     oneway deleteSmsOnRuimResponse(RadioResponseInfo info);
 
@@ -1906,6 +1918,7 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway getSmscAddressResponse(RadioResponseInfo info, string smsc);
 
@@ -1927,6 +1940,7 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway setSmscAddressResponse(RadioResponseInfo info);
 
@@ -1946,6 +1960,7 @@
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *   RadioError:SIM_ABSENT
      */
     oneway reportSmsMemoryStatusResponse(RadioResponseInfo info);
 
@@ -2024,6 +2039,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:SIM_ABSENT
      */
     oneway sendEnvelopeWithStatusResponse(RadioResponseInfo info, IccIoResult iccIo);
 
@@ -2328,6 +2344,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:SIM_ABSENT
      */
     oneway setDataProfileResponse(RadioResponseInfo info);
 
@@ -2414,6 +2431,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:SIM_ABSENT
      */
     oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
 
@@ -2430,6 +2448,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:SIM_ABSENT
      */
     oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo);
 
diff --git a/radio/1.0/vts/OWNERS b/radio/1.0/vts/OWNERS
new file mode 100644
index 0000000..2384317
--- /dev/null
+++ b/radio/1.0/vts/OWNERS
@@ -0,0 +1,8 @@
+# Telephony team
+amitmahajan@google.com
+sanketpadawe@google.com
+shuoq@google.com
+
+# VTS team
+yuexima@google.com
+yim@google.com
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index eb11b54..82a8a72 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -16,7 +16,7 @@
 
 cc_test {
     name: "VtsHalRadioV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["radio_hidl_hal_cell_broadcast.cpp",
            "radio_hidl_hal_data.cpp",
            "radio_hidl_hal_icc.cpp",
@@ -30,46 +30,22 @@
            "radio_response.cpp",
            "VtsHalRadioV1_0TargetTest.cpp",
            "vts_test_util.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
+    static_libs: [
         "android.hardware.radio@1.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
-    ],
 }
 
 cc_test {
     name: "VtsHalSapV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["sap_callback.cpp",
            "sap_hidl_hal_api.cpp",
            "sap_hidl_hal_test.cpp",
            "VtsHalSapV1_0TargetTest.cpp",
            "vts_test_util.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
+    static_libs: [
         "android.hardware.radio@1.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
-    ],
 }
 
 cc_library_static {
@@ -82,4 +58,4 @@
 cc_library_headers {
     name: "radio.util.header@1.0",
     export_include_dirs: ["."],
-}
\ No newline at end of file
+}
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/Android.bp b/radio/1.1/Android.bp
index 3a3f639..156cf99 100644
--- a/radio/1.1/Android.bp
+++ b/radio/1.1/Android.bp
@@ -60,13 +60,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.radio@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.radio@1.1_genc++"],
     generated_headers: ["android.hardware.radio@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.radio@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/radio/1.1/vts/OWNERS b/radio/1.1/vts/OWNERS
new file mode 100644
index 0000000..2384317
--- /dev/null
+++ b/radio/1.1/vts/OWNERS
@@ -0,0 +1,8 @@
+# Telephony team
+amitmahajan@google.com
+sanketpadawe@google.com
+shuoq@google.com
+
+# VTS team
+yuexima@google.com
+yim@google.com
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
index 9000eb2..e7195ee 100644
--- a/radio/1.1/vts/functional/Android.bp
+++ b/radio/1.1/vts/functional/Android.bp
@@ -16,30 +16,18 @@
 
 cc_test {
     name: "VtsHalRadioV1_1TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["radio_hidl_hal_api.cpp",
            "radio_hidl_hal_test.cpp",
            "radio_indication.cpp",
            "radio_response.cpp",
            "VtsHalRadioV1_1TargetTest.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
+    static_libs: [
+        "RadioVtsTestUtilBase",
         "android.hardware.radio@1.1",
         "android.hardware.radio@1.0",
     ],
-    static_libs: ["VtsHalHidlTargetTestBase",
-                  "RadioVtsTestUtilBase"],
     header_libs: [
         "radio.util.header@1.0",
     ],
-    cflags: [
-        "-O0",
-        "-g",
-    ],
 }
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 c6ac8a6..10f8f62 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.
@@ -61,10 +62,12 @@
     EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
+        ALOGI("startNetworkScan, rspInfo.error = %d\n", (int32_t)radioRsp_v1_1->rspInfo.error);
         ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
                     radioRsp_v1_1->rspInfo.error == RadioError::SIM_ABSENT ||
                     radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
-                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::OPERATION_NOT_ALLOWED);
     }
 }
 
@@ -84,6 +87,8 @@
     EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
+        ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %d\n",
+              (int32_t)radioRsp_v1_1->rspInfo.error);
         ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::INVALID_ARGUMENTS ||
                     radioRsp_v1_1->rspInfo.error == RadioError::SIM_ABSENT ||
                     radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
@@ -102,8 +107,144 @@
     EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
 
     if (cardStatus.cardState == CardState::ABSENT) {
+        ALOGI("stopNetworkScan rspInfo.error = %d\n", (int32_t)radioRsp_v1_1->rspInfo.error);
         ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
                     radioRsp_v1_1->rspInfo.error == RadioError::SIM_ABSENT ||
                     radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
     }
-}
\ No newline at end of file
+}
+
+/*
+ * Test IRadio.setCarrierInfoForImsiEncryption() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_1, setCarrierInfoForImsiEncryption) {
+    int serial = GetRandomSerialNumber();
+    ImsiEncryptionInfo imsiInfo;
+    imsiInfo.mcc = "310";
+    imsiInfo.mnc = "004";
+    imsiInfo.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+    imsiInfo.keyIdentifier = "Test";
+    imsiInfo.expirationTime = 20180101;
+
+    radio_v1_1->setCarrierInfoForImsiEncryption(serial, imsiInfo);
+    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);
+
+    if (cardStatus.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(radioRsp_v1_1->rspInfo.error == RadioError::NONE ||
+                    radioRsp_v1_1->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED);
+    }
+}
+
+/*
+ * 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 37b80b1..400ef3c 100644
--- a/radio/1.1/vts/functional/radio_response.cpp
+++ b/radio/1.1/vts/functional/radio_response.cpp
@@ -659,7 +659,9 @@
 
 /* 1.1 Apis */
 Return<void> RadioResponse_v1_1::setCarrierInfoForImsiEncryptionResponse(
-    const RadioResponseInfo& /*info*/) {
+    const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_1.notify();
     return Void();
 }
 
@@ -681,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/radio/deprecated/1.0/Android.bp b/radio/deprecated/1.0/Android.bp
index e45ecc3..e63ed28 100644
--- a/radio/deprecated/1.0/Android.bp
+++ b/radio/deprecated/1.0/Android.bp
@@ -49,13 +49,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.radio.deprecated@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.radio.deprecated@1.0_genc++"],
     generated_headers: ["android.hardware.radio.deprecated@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.radio.deprecated@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/renderscript/1.0/Android.bp b/renderscript/1.0/Android.bp
index d599315..0f62652 100644
--- a/renderscript/1.0/Android.bp
+++ b/renderscript/1.0/Android.bp
@@ -46,13 +46,17 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.renderscript@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.renderscript@1.0_genc++"],
     generated_headers: ["android.hardware.renderscript@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.renderscript@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp
index f6cf4a7..b2cda05 100644
--- a/sensors/1.0/Android.bp
+++ b/sensors/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.sensors@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.sensors@1.0_genc++"],
     generated_headers: ["android.hardware.sensors@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.sensors@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
index 3006508..357270f 100644
--- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
+++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp
@@ -1235,6 +1235,11 @@
 
   SensorInfo sensor = defaultSensorByType(type);
 
+  if (!isValidType(sensor.type)) {
+    // no default sensor of this type
+    return;
+  }
+
   if (!isDirectReportRateSupported(sensor, rate)) {
     return;
   }
diff --git a/soundtrigger/2.0/Android.bp b/soundtrigger/2.0/Android.bp
index 8259776..f45c4e2 100644
--- a/soundtrigger/2.0/Android.bp
+++ b/soundtrigger/2.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.soundtrigger@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.soundtrigger@2.0_genc++"],
     generated_headers: ["android.hardware.soundtrigger@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.soundtrigger@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp
index 4c76014..2dbfb0f 100644
--- a/tests/bar/1.0/Android.bp
+++ b/tests/bar/1.0/Android.bp
@@ -67,13 +67,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.bar@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.bar@1.0_genc++"],
     generated_headers: ["android.hardware.tests.bar@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.bar@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/baz/1.0/Android.bp b/tests/baz/1.0/Android.bp
index 1445b11..cec3039 100644
--- a/tests/baz/1.0/Android.bp
+++ b/tests/baz/1.0/Android.bp
@@ -60,13 +60,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.baz@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.baz@1.0_genc++"],
     generated_headers: ["android.hardware.tests.baz@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.baz@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/expression/1.0/Android.bp b/tests/expression/1.0/Android.bp
index 0cfe47d..093b660 100644
--- a/tests/expression/1.0/Android.bp
+++ b/tests/expression/1.0/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.expression@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.expression@1.0_genc++"],
     generated_headers: ["android.hardware.tests.expression@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.expression@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/extension/light/2.0/Android.bp b/tests/extension/light/2.0/Android.bp
index 6469b45..52117b4 100644
--- a/tests/extension/light/2.0/Android.bp
+++ b/tests/extension/light/2.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.extension.light@2.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.extension.light@2.0_genc++"],
     generated_headers: ["android.hardware.tests.extension.light@2.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.extension.light@2.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/foo/1.0/Android.bp b/tests/foo/1.0/Android.bp
index b698847..d0038ab 100644
--- a/tests/foo/1.0/Android.bp
+++ b/tests/foo/1.0/Android.bp
@@ -67,13 +67,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.foo@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.foo@1.0_genc++"],
     generated_headers: ["android.hardware.tests.foo@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.foo@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/hash/1.0/Android.bp b/tests/hash/1.0/Android.bp
index 617ddec..336963e 100644
--- a/tests/hash/1.0/Android.bp
+++ b/tests/hash/1.0/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.hash@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.hash@1.0_genc++"],
     generated_headers: ["android.hardware.tests.hash@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.hash@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/inheritance/1.0/Android.bp b/tests/inheritance/1.0/Android.bp
index 4dbcf4b..a8c0e6c 100644
--- a/tests/inheritance/1.0/Android.bp
+++ b/tests/inheritance/1.0/Android.bp
@@ -56,13 +56,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.inheritance@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.inheritance@1.0_genc++"],
     generated_headers: ["android.hardware.tests.inheritance@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.inheritance@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/libhwbinder/1.0/Android.bp b/tests/libhwbinder/1.0/Android.bp
index f254bad..6132628 100644
--- a/tests/libhwbinder/1.0/Android.bp
+++ b/tests/libhwbinder/1.0/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.libhwbinder@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.libhwbinder@1.0_genc++"],
     generated_headers: ["android.hardware.tests.libhwbinder@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.libhwbinder@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/memory/1.0/Android.bp b/tests/memory/1.0/Android.bp
index 5a62896..c5cc4a0 100644
--- a/tests/memory/1.0/Android.bp
+++ b/tests/memory/1.0/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.memory@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.memory@1.0_genc++"],
     generated_headers: ["android.hardware.tests.memory@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.memory@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/msgq/1.0/Android.bp b/tests/msgq/1.0/Android.bp
index 19ff89c..017e0d4 100644
--- a/tests/msgq/1.0/Android.bp
+++ b/tests/msgq/1.0/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.msgq@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.msgq@1.0_genc++"],
     generated_headers: ["android.hardware.tests.msgq@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.msgq@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/multithread/1.0/Android.bp b/tests/multithread/1.0/Android.bp
index c3782a0..68c19aa 100644
--- a/tests/multithread/1.0/Android.bp
+++ b/tests/multithread/1.0/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.multithread@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.multithread@1.0_genc++"],
     generated_headers: ["android.hardware.tests.multithread@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.multithread@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tests/pointer/1.0/Android.bp b/tests/pointer/1.0/Android.bp
index 37fea94..55598ca 100644
--- a/tests/pointer/1.0/Android.bp
+++ b/tests/pointer/1.0/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tests.pointer@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tests.pointer@1.0_genc++"],
     generated_headers: ["android.hardware.tests.pointer@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tests.pointer@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tetheroffload/Android.bp b/tetheroffload/Android.bp
index 4b50f11..f3c7021 100644
--- a/tetheroffload/Android.bp
+++ b/tetheroffload/Android.bp
@@ -1,5 +1,7 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "config/1.0",
+    "config/1.0/vts/functional",
     "control/1.0",
+    "control/1.0/vts/functional",
 ]
diff --git a/tetheroffload/config/1.0/Android.bp b/tetheroffload/config/1.0/Android.bp
index 7beefbf..2d62f16 100644
--- a/tetheroffload/config/1.0/Android.bp
+++ b/tetheroffload/config/1.0/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tetheroffload.config@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tetheroffload.config@1.0_genc++"],
     generated_headers: ["android.hardware.tetheroffload.config@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tetheroffload.config@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..2e720c6
--- /dev/null
+++ b/tetheroffload/config/1.0/vts/functional/Android.bp
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "VtsHalTetheroffloadConfigV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalTetheroffloadConfigV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
new file mode 100644
index 0000000..fc61e1c
--- /dev/null
+++ b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsOffloadConfigV1_0TargetTest"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::Void;
+using android::sp;
+
+#define ASSERT_TRUE_CALLBACK \
+    [&](bool success, const hidl_string& errMsg) { ASSERT_TRUE(success) << errMsg.c_str(); }
+
+#define ASSERT_FALSE_CALLBACK \
+    [&](bool success, const hidl_string& errMsg) { ASSERT_FALSE(success) << errMsg.c_str(); }
+
+const unsigned kFd1Groups = NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY;
+const unsigned kFd2Groups = NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY;
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int netlinkSocket(int protocol, unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, protocol));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) != 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+int netlinkSocket(unsigned groups) {
+    return netlinkSocket(NETLINK_NETFILTER, groups);
+}
+
+class OffloadConfigHidlTest : public testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+        ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+    }
+
+    virtual void TearDown() override {}
+
+    sp<IOffloadConfig> config;
+};
+
+// Ensure handles can be set with correct socket options.
+TEST_F(OffloadConfigHidlTest, TestSetHandles) {
+    unique_fd fd1(netlinkSocket(kFd1Groups));
+    if (fd1.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+    nativeHandle1->data[0] = fd1.release();
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    unique_fd fd2(netlinkSocket(kFd2Groups));
+    if (fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+    nativeHandle2->data[0] = fd2.release();
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when both FDs are empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandleNone) {
+    native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+    native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD2 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle1Only) {
+    unique_fd fd1(netlinkSocket(kFd1Groups));
+    if (fd1.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+    nativeHandle1->data[0] = fd1.release();
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    native_handle_t* const nativeHandle2 = native_handle_create(0, 0);
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+// Passing a handle without an associated file descriptor should return an error
+// (e.g. "Failed Input Checks"). Check that this occurs when FD1 is empty.
+TEST_F(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
+    native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
+    const hidl_handle h1 = hidl_handle(nativeHandle1);
+
+    unique_fd fd2(netlinkSocket(kFd2Groups));
+    if (fd2.get() < 0) {
+        ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+        FAIL();
+    }
+    native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+    nativeHandle2->data[0] = fd2.release();
+    const hidl_handle h2 = hidl_handle(nativeHandle2);
+
+    const Return<void> ret = config->setHandles(h1, h2, ASSERT_FALSE_CALLBACK);
+    ASSERT_TRUE(ret.isOk());
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGE("Test result with status=%d", status);
+    return status;
+}
diff --git a/tetheroffload/control/1.0/Android.bp b/tetheroffload/control/1.0/Android.bp
index d351edb..72f410e 100644
--- a/tetheroffload/control/1.0/Android.bp
+++ b/tetheroffload/control/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tetheroffload.control@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tetheroffload.control@1.0_genc++"],
     generated_headers: ["android.hardware.tetheroffload.control@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tetheroffload.control@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..69fac6e
--- /dev/null
+++ b/tetheroffload/control/1.0/vts/functional/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "VtsHalTetheroffloadControlV1_0TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalTetheroffloadControlV1_0TargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.tetheroffload.config@1.0",
+        "android.hardware.tetheroffload.control@1.0",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
new file mode 100644
index 0000000..3059eac
--- /dev/null
+++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsOffloadControlV1_0TargetTest"
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <android/hardware/tetheroffload/control/1.0/IOffloadControl.h>
+#include <android/hardware/tetheroffload/control/1.0/types.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netlink.h>
+#include <log/log.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <set>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::tetheroffload::config::V1_0::IOffloadConfig;
+using android::hardware::tetheroffload::control::V1_0::IOffloadControl;
+using android::hardware::tetheroffload::control::V1_0::IPv4AddrPortPair;
+using android::hardware::tetheroffload::control::V1_0::ITetheringOffloadCallback;
+using android::hardware::tetheroffload::control::V1_0::OffloadCallbackEvent;
+using android::hardware::tetheroffload::control::V1_0::NatTimeoutUpdate;
+using android::hardware::tetheroffload::control::V1_0::NetworkProtocol;
+using android::hardware::Void;
+using android::sp;
+
+// We use #defines here so as to get local lamba captures and error message line numbers
+#define ASSERT_TRUE_CALLBACK                            \
+    [&](bool success, std::string errMsg) {             \
+        if (!success) {                                 \
+            ALOGI("Error message: %s", errMsg.c_str()); \
+        }                                               \
+        ASSERT_TRUE(success);                           \
+    }
+
+#define ASSERT_FALSE_CALLBACK                           \
+    [&](bool success, std::string errMsg) {             \
+        if (!success) {                                 \
+            ALOGI("Error message: %s", errMsg.c_str()); \
+        }                                               \
+        ASSERT_FALSE(success);                          \
+    }
+
+#define ASSERT_ZERO_BYTES_CALLBACK            \
+    [&](uint64_t rxBytes, uint64_t txBytes) { \
+        EXPECT_EQ(0ULL, rxBytes);             \
+        EXPECT_EQ(0ULL, txBytes);             \
+    }
+
+inline const sockaddr* asSockaddr(const sockaddr_nl* nladdr) {
+    return reinterpret_cast<const sockaddr*>(nladdr);
+}
+
+int conntrackSocket(unsigned groups) {
+    unique_fd s(socket(AF_NETLINK, SOCK_DGRAM, NETLINK_NETFILTER));
+    if (s.get() < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl bind_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (::bind(s.get(), asSockaddr(&bind_addr), sizeof(bind_addr)) < 0) {
+        return -errno;
+    }
+
+    const struct sockaddr_nl kernel_addr = {
+        .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = groups,
+    };
+    if (connect(s.get(), asSockaddr(&kernel_addr), sizeof(kernel_addr)) != 0) {
+        return -errno;
+    }
+
+    return s.release();
+}
+
+constexpr char kCallbackOnEvent[] = "onEvent";
+constexpr char kCallbackUpdateTimeout[] = "updateTimeout";
+
+class TetheringOffloadCallbackArgs {
+   public:
+    OffloadCallbackEvent last_event;
+    NatTimeoutUpdate last_params;
+};
+
+class OffloadControlHidlTestBase : public testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        prepareControlHal();
+    }
+
+    virtual void TearDown() override { stopOffload(false); }
+
+    // The IOffloadConfig HAL is tested more thoroughly elsewhere. He we just
+    // setup everything correctly and verify basic readiness.
+    void setupConfigHal() {
+        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>();
+        ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
+
+        unique_fd fd1(conntrackSocket(NFNLGRP_CONNTRACK_NEW | NFNLGRP_CONNTRACK_DESTROY));
+        if (fd1.get() < 0) {
+            ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+            FAIL();
+        }
+        native_handle_t* const nativeHandle1 = native_handle_create(1, 0);
+        nativeHandle1->data[0] = fd1.release();
+        hidl_handle h1 = hidl_handle(nativeHandle1);
+
+        unique_fd fd2(conntrackSocket(NFNLGRP_CONNTRACK_UPDATE | NFNLGRP_CONNTRACK_DESTROY));
+        if (fd2.get() < 0) {
+            ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
+            FAIL();
+        }
+        native_handle_t* const nativeHandle2 = native_handle_create(1, 0);
+        nativeHandle2->data[0] = fd2.release();
+        hidl_handle h2 = hidl_handle(nativeHandle2);
+
+        const Return<void> ret = config->setHandles(h1, h2, ASSERT_TRUE_CALLBACK);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void prepareControlHal() {
+        control = testing::VtsHalHidlTargetTestBase::getService<IOffloadControl>();
+        ASSERT_NE(nullptr, control.get()) << "Could not get HIDL instance";
+
+        control_cb = new TetheringOffloadCallback();
+        ASSERT_NE(nullptr, control_cb.get()) << "Could not get get offload callback";
+    }
+
+    void initOffload(const bool expected_result) {
+        auto init_cb = [&](bool success, std::string errMsg) {
+            if (!success) {
+                ALOGI("Error message: %s", errMsg.c_str());
+            }
+            ASSERT_EQ(expected_result, success);
+        };
+        const Return<void> ret = control->initOffload(control_cb, init_cb);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    void setupControlHal() {
+        prepareControlHal();
+        initOffload(true);
+    }
+
+    void stopOffload(const bool expected_result) {
+        auto cb = [&](bool success, const hidl_string& errMsg) {
+            if (!success) {
+                ALOGI("Error message: %s", errMsg.c_str());
+            }
+            ASSERT_EQ(expected_result, success);
+        };
+        const Return<void> ret = control->stopOffload(cb);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    // Callback class for both events and NAT timeout updates.
+    class TetheringOffloadCallback
+        : public testing::VtsHalHidlTargetCallbackBase<TetheringOffloadCallbackArgs>,
+          public ITetheringOffloadCallback {
+       public:
+        TetheringOffloadCallback() = default;
+        virtual ~TetheringOffloadCallback() = default;
+
+        Return<void> onEvent(OffloadCallbackEvent event) override {
+            const TetheringOffloadCallbackArgs args{.last_event = event};
+            NotifyFromCallback(kCallbackOnEvent, args);
+            return Void();
+        };
+
+        Return<void> updateTimeout(const NatTimeoutUpdate& params) override {
+            const TetheringOffloadCallbackArgs args{.last_params = params};
+            NotifyFromCallback(kCallbackUpdateTimeout, args);
+            return Void();
+        };
+    };
+
+    sp<IOffloadConfig> config;
+    sp<IOffloadControl> control;
+    sp<TetheringOffloadCallback> control_cb;
+};
+
+// Call initOffload() multiple times. Check that non-first initOffload() calls return false.
+TEST_F(OffloadControlHidlTestBase, AdditionalInitsWithoutStopReturnFalse) {
+    initOffload(true);
+    initOffload(false);
+    initOffload(false);
+    initOffload(false);
+    stopOffload(true);  // balance out initOffload(true)
+}
+
+// Check that calling stopOffload() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, MultipleStopsWithoutInitReturnFalse) {
+    stopOffload(false);
+    stopOffload(false);
+    stopOffload(false);
+}
+
+// Check that calling stopOffload() after a complete init/stop cycle returns false.
+TEST_F(OffloadControlHidlTestBase, AdditionalStopsWithInitReturnFalse) {
+    initOffload(true);
+    stopOffload(true);  // balance out initOffload(true)
+    stopOffload(false);
+    stopOffload(false);
+}
+
+// Check that calling setLocalPrefixes() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetLocalPrefixesWithoutInitReturnsFalse) {
+    const vector<hidl_string> prefixes{hidl_string("2001:db8::/64")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling getForwardedStats() without first having called initOffload()
+// returns zero bytes statistics.
+TEST_F(OffloadControlHidlTestBase, GetForwardedStatsWithoutInitReturnsZeroValues) {
+    const hidl_string upstream("rmnet_data0");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setDataLimit() without first having called initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, SetDataLimitWithoutInitReturnsFalse) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling setUpstreamParameters() without first having called initOffload()
+// returns false.
+TEST_F(OffloadControlHidlTestBase, SetUpstreamParametersWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.0/24");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv4DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling addDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, AddIPv6DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv4 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv4DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Check that calling removeDownstream() with an IPv6 prefix without first having called
+// initOffload() returns false.
+TEST_F(OffloadControlHidlTestBase, RemoveIPv6DownstreamWithoutInitReturnsFalse) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+class OffloadControlHidlTest : public OffloadControlHidlTestBase {
+   public:
+    virtual void SetUp() override {
+        setupConfigHal();
+        setupControlHal();
+    }
+
+    virtual void TearDown() override { stopOffload(true); }
+};
+
+/*
+ * Tests for IOffloadControl::setLocalPrefixes().
+ */
+
+// Test setLocalPrefixes() accepts an IPv4 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4AddressOk) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.1")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts an IPv6 address.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv6AddressOk) {
+    const vector<hidl_string> prefixes{hidl_string("fe80::1")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesIPv4v6PrefixesOk) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("fe80::/64")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setLocalPrefixes() fails given empty input. There is always
+// a non-empty set of local prefixes; when all networking interfaces are down
+// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesEmptyFails) {
+    const vector<hidl_string> prefixes{};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test setLocalPrefixes() fails on incorrectly formed input strings.
+TEST_F(OffloadControlHidlTest, SetLocalPrefixesInvalidFails) {
+    const vector<hidl_string> prefixes{hidl_string("192.0.2.0/24"), hidl_string("invalid")};
+    const Return<void> ret = control->setLocalPrefixes(prefixes, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::getForwardedStats().
+ */
+
+// Test that getForwardedStats() for a non-existent upstream yields zero bytes statistics.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsInvalidUpstreamIface) {
+    const hidl_string upstream("invalid");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, GetForwardedStatsDummyIface) {
+    const hidl_string upstream("rmnet_data0");
+    const Return<void> ret = control->getForwardedStats(upstream, ASSERT_ZERO_BYTES_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setDataLimit().
+ */
+
+// Test that setDataLimit() for an empty interface name fails.
+TEST_F(OffloadControlHidlTest, SetDataLimitEmptyUpstreamIfaceFails) {
+    const hidl_string upstream("");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitNonZeroOk) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 5000ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetDataLimitZeroOk) {
+    const hidl_string upstream("rmnet_data0");
+    const uint64_t limit = 0ULL;
+    const Return<void> ret = control->setDataLimit(upstream, limit, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+/*
+ * Tests for IOffloadControl::setUpstreamParameters().
+ */
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv6OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("");
+    const hidl_string v4Gw("");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersAlternateIPv6OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr;
+    const hidl_string v4Gw;
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:3")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4OnlyOk) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// The "rmnet_data0" is presumed to exist on the device and be up. No packets
+// are ever actually caused to be forwarded.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersIPv4v6Ok) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1"), hidl_string("fe80::db8:2")};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when all parameters are empty.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string v4Addr("");
+    const hidl_string v4Gw("");
+    const vector<hidl_string> v6Gws{};
+    const Return<void> ret =
+        control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBogusIfaceFails) {
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 addresses.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4AddrFails) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Gw("192.0.2.1");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(StringPrintf("v4addr='%s'", bogus));
+        const hidl_string v4Addr(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv4 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersInvalidIPv4GatewayFails) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const vector<hidl_string> v6Gws{hidl_string("fe80::db8:1")};
+    for (const auto& bogus : {"invalid", "192.0.2"}) {
+        SCOPED_TRACE(StringPrintf("v4gateway='%s'", bogus));
+        const hidl_string v4Gw(bogus);
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test that setUpstreamParameters() fails when given unparseable IPv6 gateways.
+TEST_F(OffloadControlHidlTest, SetUpstreamParametersBadIPv6GatewaysFail) {
+    const hidl_string iface("rmnet_data0");
+    const hidl_string v4Addr("192.0.2.2");
+    const hidl_string v4Gw("192.0.2.1");
+    for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
+        SCOPED_TRACE(StringPrintf("v6gateway='%s'", bogus));
+        const vector<hidl_string> v6Gws{hidl_string("fe80::1"), hidl_string(bogus)};
+        const Return<void> ret =
+            control->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+/*
+ * Tests for IOffloadControl::addDownstream().
+ */
+
+// Test addDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv4) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, AddDownstreamIPv6) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, AddDownstreamEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string prefix("");
+    const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test addDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, AddDownstreamInvalidIfaceFails) {
+    const hidl_string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test addDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, AddDownstreamBogusPrefixFails) {
+    const hidl_string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+        const hidl_string prefix(bogus);
+        const Return<void> ret = control->addDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+/*
+ * Tests for IOffloadControl::removeDownstream().
+ */
+
+// Test removeDownstream() works given an IPv4 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv4) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("192.0.2.0/24");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() works given an IPv6 prefix.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamIPv6) {
+    const hidl_string iface("dummy0");
+    const hidl_string prefix("2001:db8::/64");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_TRUE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given all empty parameters.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamEmptyFails) {
+    const hidl_string iface("");
+    const hidl_string prefix("");
+    const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+    EXPECT_TRUE(ret.isOk());
+}
+
+// Test removeDownstream() fails given empty or non-existent interface names.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusIfaceFails) {
+    const hidl_string prefix("192.0.2.0/24");
+    for (const auto& bogus : {"", "invalid"}) {
+        SCOPED_TRACE(StringPrintf("iface='%s'", bogus));
+        const hidl_string iface(bogus);
+        const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+// Test removeDownstream() fails given unparseable prefix arguments.
+TEST_F(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) {
+    const hidl_string iface("dummy0");
+    for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
+        SCOPED_TRACE(StringPrintf("prefix='%s'", bogus));
+        const hidl_string prefix(bogus);
+        const Return<void> ret = control->removeDownstream(iface, prefix, ASSERT_FALSE_CALLBACK);
+        EXPECT_TRUE(ret.isOk());
+    }
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGE("Test result with status=%d", status);
+    return status;
+}
diff --git a/thermal/1.0/Android.bp b/thermal/1.0/Android.bp
index 6a9f9c7..aa97175 100644
--- a/thermal/1.0/Android.bp
+++ b/thermal/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.thermal@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.thermal@1.0_genc++"],
     generated_headers: ["android.hardware.thermal@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.thermal@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/thermal/1.1/Android.bp b/thermal/1.1/Android.bp
new file mode 100644
index 0000000..833f219
--- /dev/null
+++ b/thermal/1.1/Android.bp
@@ -0,0 +1,68 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+filegroup {
+    name: "android.hardware.thermal@1.1_hal",
+    srcs: [
+        "IThermal.hal",
+        "IThermalCallback.hal",
+    ],
+}
+
+genrule {
+    name: "android.hardware.thermal@1.1_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.thermal@1.1",
+    srcs: [
+        ":android.hardware.thermal@1.1_hal",
+    ],
+    out: [
+        "android/hardware/thermal/1.1/ThermalAll.cpp",
+        "android/hardware/thermal/1.1/ThermalCallbackAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.thermal@1.1_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.thermal@1.1",
+    srcs: [
+        ":android.hardware.thermal@1.1_hal",
+    ],
+    out: [
+        "android/hardware/thermal/1.1/IThermal.h",
+        "android/hardware/thermal/1.1/IHwThermal.h",
+        "android/hardware/thermal/1.1/BnHwThermal.h",
+        "android/hardware/thermal/1.1/BpHwThermal.h",
+        "android/hardware/thermal/1.1/BsThermal.h",
+        "android/hardware/thermal/1.1/IThermalCallback.h",
+        "android/hardware/thermal/1.1/IHwThermalCallback.h",
+        "android/hardware/thermal/1.1/BnHwThermalCallback.h",
+        "android/hardware/thermal/1.1/BpHwThermalCallback.h",
+        "android/hardware/thermal/1.1/BsThermalCallback.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.thermal@1.1",
+    defaults: ["hidl-module-defaults"],
+    generated_sources: ["android.hardware.thermal@1.1_genc++"],
+    generated_headers: ["android.hardware.thermal@1.1_genc++_headers"],
+    export_generated_headers: ["android.hardware.thermal@1.1_genc++_headers"],
+    vendor_available: true,
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.thermal@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.thermal@1.0",
+    ],
+}
diff --git a/thermal/1.1/Android.mk b/thermal/1.1/Android.mk
new file mode 100644
index 0000000..082d65b
--- /dev/null
+++ b/thermal/1.1/Android.mk
@@ -0,0 +1,120 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.thermal-V1.1-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.thermal-V1.0-java \
+    android.hidl.base-V1.0-java \
+
+
+#
+# Build IThermal.hal
+#
+GEN := $(intermediates)/android/hardware/thermal/V1_1/IThermal.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IThermal.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IThermalCallback.hal
+$(GEN): $(LOCAL_PATH)/IThermalCallback.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.thermal@1.1::IThermal
+
+$(GEN): $(LOCAL_PATH)/IThermal.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IThermalCallback.hal
+#
+GEN := $(intermediates)/android/hardware/thermal/V1_1/IThermalCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IThermalCallback.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.thermal@1.1::IThermalCallback
+
+$(GEN): $(LOCAL_PATH)/IThermalCallback.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.thermal-V1.1-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(call local-generated-sources-dir, COMMON)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hardware.thermal-V1.0-java-static \
+    android.hidl.base-V1.0-java-static \
+
+
+#
+# Build IThermal.hal
+#
+GEN := $(intermediates)/android/hardware/thermal/V1_1/IThermal.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IThermal.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/IThermalCallback.hal
+$(GEN): $(LOCAL_PATH)/IThermalCallback.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.thermal@1.1::IThermal
+
+$(GEN): $(LOCAL_PATH)/IThermal.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build IThermalCallback.hal
+#
+GEN := $(intermediates)/android/hardware/thermal/V1_1/IThermalCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IThermalCallback.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.thermal@1.1::IThermalCallback
+
+$(GEN): $(LOCAL_PATH)/IThermalCallback.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/thermal/1.1/IThermal.hal b/thermal/1.1/IThermal.hal
new file mode 100644
index 0000000..14f35ba
--- /dev/null
+++ b/thermal/1.1/IThermal.hal
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal@1.1;
+
+import android.hardware.thermal@1.0::IThermal;
+import IThermalCallback;
+
+interface IThermal extends @1.0::IThermal {
+   /**
+    * Register an IThermalCallback, used by the Thermal HAL
+    * to send thermal events to the framework thermal service.
+    *
+    * @param callback the IThermalCallback to use for sending
+    *        thermal events, or nullptr to set no callback
+    */
+    registerThermalCallback(IThermalCallback callback);
+};
diff --git a/thermal/1.1/IThermalCallback.hal b/thermal/1.1/IThermalCallback.hal
new file mode 100644
index 0000000..f418ec3
--- /dev/null
+++ b/thermal/1.1/IThermalCallback.hal
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.thermal@1.1;
+
+import android.hardware.thermal@1.0::Temperature;
+
+/**
+ * IThermalCallback connects vendor code to the framework binder ThermalService.
+ */
+interface IThermalCallback {
+    /**
+     * Send a thermal throttling start/stop event to all ThermalService
+     * thermal event listeners.
+     * @param isThrottling true if device is currently throttling
+     * @param temperature The temperature associated with the throttling
+     *        start/stop event
+     */
+    oneway notifyThrottling(bool isThrottling, Temperature temperature);
+};
diff --git a/thermal/1.1/vts/functional/Android.bp b/thermal/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..cea5bf8
--- /dev/null
+++ b/thermal/1.1/vts/functional/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalThermalV1_1TargetTest",
+    defaults: ["hidl_defaults"],
+    srcs: ["VtsHalThermalV1_1TargetTest.cpp"],
+    shared_libs: [
+        "liblog",
+        "libhidlbase",
+        "libhidltransport",
+        "libutils",
+        "android.hardware.thermal@1.0",
+        "android.hardware.thermal@1.1",
+    ],
+    static_libs: ["VtsHalHidlTargetTestBase"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
diff --git a/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp b/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp
new file mode 100644
index 0000000..6c1599b
--- /dev/null
+++ b/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/thermal/1.1/IThermal.h>
+#include <android/hardware/thermal/1.1/IThermalCallback.h>
+#include <android/hardware/thermal/1.0/types.h>
+
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::thermal::V1_0::Temperature;
+using ::android::hardware::thermal::V1_0::TemperatureType;
+using ::android::hardware::thermal::V1_1::IThermal;
+using ::android::hardware::thermal::V1_1::IThermalCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+constexpr char kCallbackNameNotifyThrottling[] = "notifyThrottling";
+static const Temperature kThrottleTemp = {
+    .type = TemperatureType::CPU,
+    .name = "test temperature sensor",
+    .currentValue = 98.6,
+    .throttlingThreshold = 58,
+    .shutdownThreshold = 60,
+    .vrThrottlingThreshold = 59,
+};
+
+class ThermalCallbackArgs {
+   public:
+     bool isThrottling;
+     Temperature temperature;
+};
+
+// Callback class for receiving thermal event notifications from main class
+class ThermalCallback
+    : public ::testing::VtsHalHidlTargetCallbackBase<ThermalCallbackArgs>,
+      public IThermalCallback {
+   public:
+    virtual ~ThermalCallback() = default;
+
+    Return<void> notifyThrottling(bool isThrottling,
+                                  const Temperature& temperature) override {
+        ThermalCallbackArgs args;
+        args.isThrottling = isThrottling;
+        args.temperature = temperature;
+        NotifyFromCallback(kCallbackNameNotifyThrottling, args);
+        return Void();
+    }
+};
+
+// The main test class for THERMAL HIDL HAL 1.1.
+class ThermalHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+   public:
+    virtual void SetUp() override {
+        mThermal = ::testing::VtsHalHidlTargetTestBase::getService<IThermal>();
+        ASSERT_NE(mThermal, nullptr);
+        mThermalCallback = new(std::nothrow) ThermalCallback();
+        ASSERT_NE(mThermalCallback, nullptr);
+        auto ret = mThermal->registerThermalCallback(mThermalCallback);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+    virtual void TearDown() override {
+        auto ret = mThermal->registerThermalCallback(nullptr);
+        ASSERT_TRUE(ret.isOk());
+    }
+
+   protected:
+    sp<IThermal> mThermal;
+    sp<ThermalCallback> mThermalCallback;
+}; // class ThermalHidlTest
+
+// Test ThermalCallback::notifyThrottling().
+// This just calls into and back from our local ThermalCallback impl.
+// Note: a real thermal throttling event from the Thermal HAL could be
+// inadvertently received here.
+TEST_F(ThermalHidlTest, NotifyThrottlingTest) {
+    auto ret = mThermalCallback->notifyThrottling(true, kThrottleTemp);
+    ASSERT_TRUE(ret.isOk());
+    auto res = mThermalCallback->WaitForCallback(kCallbackNameNotifyThrottling);
+    EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.args);
+    EXPECT_EQ(true, res.args->isThrottling);
+    EXPECT_EQ(kThrottleTemp, res.args->temperature);
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    cout << "Test result = " << status << std::endl;
+    return status;
+}
diff --git a/thermal/Android.bp b/thermal/Android.bp
index ed19a37..a5415df 100644
--- a/thermal/Android.bp
+++ b/thermal/Android.bp
@@ -3,4 +3,6 @@
     "1.0",
     "1.0/default",
     "1.0/vts/functional",
+    "1.1",
+    "1.1/vts/functional",
 ]
diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp
index bf3ffe2..c9da737 100644
--- a/tv/cec/1.0/Android.bp
+++ b/tv/cec/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tv.cec@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tv.cec@1.0_genc++"],
     generated_headers: ["android.hardware.tv.cec@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tv.cec@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/tv/input/1.0/Android.bp b/tv/input/1.0/Android.bp
index a3f8c94..22ea1d8 100644
--- a/tv/input/1.0/Android.bp
+++ b/tv/input/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.tv.input@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.tv.input@1.0_genc++"],
     generated_headers: ["android.hardware.tv.input@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.tv.input@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/usb/1.0/Android.bp b/usb/1.0/Android.bp
index b03f75b..afe1931 100644
--- a/usb/1.0/Android.bp
+++ b/usb/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.usb@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.usb@1.0_genc++"],
     generated_headers: ["android.hardware.usb@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.usb@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/usb/1.1/Android.bp b/usb/1.1/Android.bp
index f067606..5466001 100644
--- a/usb/1.1/Android.bp
+++ b/usb/1.1/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.usb@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.usb@1.1_genc++"],
     generated_headers: ["android.hardware.usb@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.usb@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/vibrator/1.0/Android.bp b/vibrator/1.0/Android.bp
index 0beff68..354b83f 100644
--- a/vibrator/1.0/Android.bp
+++ b/vibrator/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.vibrator@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.vibrator@1.0_genc++"],
     generated_headers: ["android.hardware.vibrator@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.vibrator@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/vibrator/1.1/Android.bp b/vibrator/1.1/Android.bp
index ee81d83..a47f37c 100644
--- a/vibrator/1.1/Android.bp
+++ b/vibrator/1.1/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.vibrator@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.vibrator@1.1_genc++"],
     generated_headers: ["android.hardware.vibrator@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.vibrator@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/vr/1.0/Android.bp b/vr/1.0/Android.bp
index d6949c5..cb9e2af 100644
--- a/vr/1.0/Android.bp
+++ b/vr/1.0/Android.bp
@@ -35,13 +35,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.vr@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.vr@1.0_genc++"],
     generated_headers: ["android.hardware.vr@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.vr@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/weaver/1.0/Android.bp b/weaver/1.0/Android.bp
index b64391c..cdc59c9 100644
--- a/weaver/1.0/Android.bp
+++ b/weaver/1.0/Android.bp
@@ -39,13 +39,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.weaver@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.weaver@1.0_genc++"],
     generated_headers: ["android.hardware.weaver@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.weaver@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/wifi/1.0/Android.bp b/wifi/1.0/Android.bp
index c8b694c..d7db770 100644
--- a/wifi/1.0/Android.bp
+++ b/wifi/1.0/Android.bp
@@ -123,13 +123,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.wifi@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.wifi@1.0_genc++"],
     generated_headers: ["android.hardware.wifi@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.wifi@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index 2d6679f..0cebbfc 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -38,50 +38,30 @@
 
 cc_test {
     name: "VtsHalWifiV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "VtsHalWifiV1_0TargetTest.cpp",
         "wifi_ap_iface_hidl_test.cpp",
         "wifi_chip_hidl_test.cpp",
         "wifi_p2p_iface_hidl_test.cpp",
         "wifi_rtt_controller_hidl_test.cpp",
-        "wifi_sta_iface_hidl_test.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
-        "android.hardware.wifi@1.0",
+        "wifi_sta_iface_hidl_test.cpp",
     ],
-    static_libs: ["VtsHalWifiV1_0TargetTestUtil", "VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi@1.0",
     ],
 }
 
 cc_test {
     name: "VtsHalWifiNanV1_0TargetTest",
-    defaults: ["hidl_defaults"],
+    defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "VtsHalWifiV1_0TargetTest.cpp",
-        "wifi_nan_iface_hidl_test.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
-        "android.hardware.wifi@1.0",
+        "wifi_nan_iface_hidl_test.cpp",
     ],
-    static_libs: ["VtsHalWifiV1_0TargetTestUtil", "VtsHalHidlTargetTestBase"],
-    cflags: [
-        "-O0",
-        "-g",
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi@1.0",
     ],
 }
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
index 06e21ff..3c23135 100644
--- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -182,6 +182,8 @@
         EXPECT_EQ(WifiStatusCode::SUCCESS,
                   HIDL_INVOKE(wifi_chip_, configureChip, mode.id).code);
         stopWifi();
+        // Sleep for 5 milliseconds between each wifi state toggle.
+        usleep(5000);
     }
 }
 
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
index e4382bc..0851cb2 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -206,5 +206,7 @@
 void stopWifi() {
     sp<IWifi> wifi = getWifi();
     ASSERT_NE(wifi, nullptr);
-    ASSERT_EQ(HIDL_INVOKE(wifi, stop).code, WifiStatusCode::SUCCESS);
+    const auto status = HIDL_INVOKE(wifi, stop);
+    ASSERT_TRUE((status.code == WifiStatusCode::SUCCESS) ||
+                (status.code == WifiStatusCode::ERROR_NOT_AVAILABLE));
 }
diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp
index f991fa5..aa6e937 100644
--- a/wifi/1.1/Android.bp
+++ b/wifi/1.1/Android.bp
@@ -42,13 +42,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.wifi@1.1",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.wifi@1.1_genc++"],
     generated_headers: ["android.hardware.wifi@1.1_genc++_headers"],
     export_generated_headers: ["android.hardware.wifi@1.1_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/wifi/1.1/IWifiChip.hal b/wifi/1.1/IWifiChip.hal
index 50cd02d..1af1f71 100644
--- a/wifi/1.1/IWifiChip.hal
+++ b/wifi/1.1/IWifiChip.hal
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 The Android Open Source Project
+ * Copyright 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,24 +44,40 @@
   };
 
   /**
-   * API to set TX power limit.
-   * This is used for meeting SAR requirements while making VOIP calls for
-   * example.
-   *
-   * @param powerInDbm Power level in dBm.
-   * @return status WifiStatus of the operation.
-   *         Possible status codes:
-   *         |WifiStatusCode.SUCCESS|,
-   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
-   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
-   *         |WifiStatusCode.NOT_AVAILABLE|,
-   *         |WifiStatusCode.UNKNOWN|
+   * List of preset wifi radio TX power levels for different scenarios.
+   * The actual power values (typically varies based on the channel,
+   * 802.11 connection type, number of MIMO streams, etc) for each scenario
+   * is defined by the OEM as a BDF file since it varies for each wifi chip
+   * vendor and device.
    */
-  setTxPowerLimit(int32_t powerInDbm) generates (WifiStatus status);
+  enum TxPowerScenario : uint32_t {
+    VOICE_CALL = 0,
+  };
 
   /**
-   * API to reset TX power limit.
-   * This is used to set the power back to default values.
+   * API to select one of the preset TX power scenarios.
+   *
+   * The framework must invoke this method with the appropriate scenario to let
+   * the wifi chip change it's transmitting power levels.
+   * OEM's should define various power profiles for each of the scenarios
+   * above (defined in |TxPowerScenario|).
+   *
+   * @param scenario One of the preselected scenarios defined in
+   *        |TxPowerScenario|.
+   * @return status WifiStatus of the operation.
+   *         Possible status codes:
+   *         |WifiStatusCode.SUCCESS|,
+   *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+   *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+   *         |WifiStatusCode.NOT_AVAILABLE|,
+   *         |WifiStatusCode.UNKNOWN|
+   */
+  selectTxPowerScenario(TxPowerScenario scenario) generates (WifiStatus status);
+
+  /**
+   * API to reset TX power levels.
+   * This is used to indicate the end of the previously selected TX power
+   * scenario and let the wifi chip fall back to the default power values.
    *
    * @return status WifiStatus of the operation.
    *         Possible status codes:
@@ -71,5 +87,5 @@
    *         |WifiStatusCode.NOT_AVAILABLE|,
    *         |WifiStatusCode.UNKNOWN|
    */
-  resetTxPowerLimit() generates (WifiStatus status);
+  resetTxPowerScenario() generates (WifiStatus status);
 };
diff --git a/wifi/1.1/default/hidl_struct_util.cpp b/wifi/1.1/default/hidl_struct_util.cpp
index 6b93b9e..c53cdc5 100644
--- a/wifi/1.1/default/hidl_struct_util.cpp
+++ b/wifi/1.1/default/hidl_struct_util.cpp
@@ -17,9 +17,6 @@
 #include <android-base/logging.h>
 #include <utils/SystemClock.h>
 
-#include <android/hardware/wifi/1.0/IWifiChip.h>
-#include <android/hardware/wifi/1.1/IWifiChip.h>
-
 #include "hidl_struct_util.h"
 
 namespace android {
@@ -260,6 +257,15 @@
   return true;
 }
 
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+    V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
+  switch (hidl_scenario) {
+    case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL:
+      return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
+  };
+  CHECK(false);
+}
+
 bool convertLegacyFeaturesToHidlStaCapabilities(
     uint32_t legacy_feature_set,
     uint32_t legacy_logger_feature_set,
diff --git a/wifi/1.1/default/hidl_struct_util.h b/wifi/1.1/default/hidl_struct_util.h
index 7a840f9..747fd2f 100644
--- a/wifi/1.1/default/hidl_struct_util.h
+++ b/wifi/1.1/default/hidl_struct_util.h
@@ -20,6 +20,8 @@
 #include <vector>
 
 #include <android/hardware/wifi/1.0/types.h>
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.1/IWifiChip.h>
 
 #include "wifi_legacy_hal.h"
 
@@ -51,6 +53,8 @@
 bool convertLegacyWakeReasonStatsToHidl(
     const legacy_hal::WakeReasonStats& legacy_stats,
     WifiDebugHostWakeReasonStats* hidl_stats);
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+    V1_1::IWifiChip::TxPowerScenario hidl_scenario);
 
 // STA iface conversion methods.
 bool convertLegacyFeaturesToHidlStaCapabilities(
diff --git a/wifi/1.1/default/service.cpp b/wifi/1.1/default/service.cpp
index b3fcd50..b4aed6c 100644
--- a/wifi/1.1/default/service.cpp
+++ b/wifi/1.1/default/service.cpp
@@ -27,7 +27,7 @@
 int main(int /*argc*/, char** argv) {
   android::base::InitLogging(argv,
                              android::base::LogdLogger(android::base::SYSTEM));
-  LOG(INFO) << "Wifi Hal is starting up...";
+  LOG(INFO) << "Wifi Hal is booting up...";
 
   configureRpcThreadpool(1, true /* callerWillJoin */);
 
diff --git a/wifi/1.1/default/wifi.cpp b/wifi/1.1/default/wifi.cpp
index fe4f642..8456b90 100644
--- a/wifi/1.1/default/wifi.cpp
+++ b/wifi/1.1/default/wifi.cpp
@@ -108,14 +108,15 @@
         LOG(ERROR) << "Failed to invoke onStart callback";
       };
     }
+    LOG(INFO) << "Wifi HAL started";
   } else {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
       if (!callback->onFailure(wifi_status).isOk()) {
         LOG(ERROR) << "Failed to invoke onFailure callback";
       }
     }
+    LOG(ERROR) << "Wifi HAL start failed";
   }
-  LOG(INFO) << "Wifi HAL started";
   return wifi_status;
 }
 
@@ -139,14 +140,15 @@
         LOG(ERROR) << "Failed to invoke onStop callback";
       };
     }
+    LOG(INFO) << "Wifi HAL stopped";
   } else {
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
       if (!callback->onFailure(wifi_status).isOk()) {
         LOG(ERROR) << "Failed to invoke onFailure callback";
       }
     }
+    LOG(ERROR) << "Wifi HAL stop failed";
   }
-  LOG(INFO) << "Wifi HAL stopped";
   return wifi_status;
 }
 
diff --git a/wifi/1.1/default/wifi_chip.cpp b/wifi/1.1/default/wifi_chip.cpp
index 2beac26..2f40234 100644
--- a/wifi/1.1/default/wifi_chip.cpp
+++ b/wifi/1.1/default/wifi_chip.cpp
@@ -343,20 +343,20 @@
                          enable);
 }
 
-Return<void> WifiChip::setTxPowerLimit(
-    int32_t powerInDbm, setTxPowerLimit_cb hidl_status_cb) {
+Return<void> WifiChip::selectTxPowerScenario(
+    TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
   return validateAndCall(this,
                          WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                         &WifiChip::setTxPowerLimitInternal,
+                         &WifiChip::selectTxPowerScenarioInternal,
                          hidl_status_cb,
-                         powerInDbm);
+                         scenario);
 }
 
-Return<void> WifiChip::resetTxPowerLimit(
-    resetTxPowerLimit_cb hidl_status_cb) {
+Return<void> WifiChip::resetTxPowerScenario(
+    resetTxPowerScenario_cb hidl_status_cb) {
   return validateAndCall(this,
                          WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                         &WifiChip::resetTxPowerLimitInternal,
+                         &WifiChip::resetTxPowerScenarioInternal,
                          hidl_status_cb);
 }
 
@@ -824,13 +824,14 @@
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiChip::setTxPowerLimitInternal(int32_t powerInDbm) {
-  auto legacy_status = legacy_hal_.lock()->setTxPowerLimit(powerInDbm);
+WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
+  auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
+      hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiChip::resetTxPowerLimitInternal() {
-  auto legacy_status = legacy_hal_.lock()->resetTxPowerLimit();
+WifiStatus WifiChip::resetTxPowerScenarioInternal() {
+  auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario();
   return createWifiStatusFromLegacyError(legacy_status);
 }
 
diff --git a/wifi/1.1/default/wifi_chip.h b/wifi/1.1/default/wifi_chip.h
index b7dde50..e88100b 100644
--- a/wifi/1.1/default/wifi_chip.h
+++ b/wifi/1.1/default/wifi_chip.h
@@ -126,9 +126,11 @@
       getDebugHostWakeReasonStats_cb hidl_status_cb) override;
   Return<void> enableDebugErrorAlerts(
       bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override;
-  Return<void> setTxPowerLimit(
-      int32_t powerInDbm, setTxPowerLimit_cb hidl_status_cb) override;
-  Return<void> resetTxPowerLimit(resetTxPowerLimit_cb hidl_status_cb) override;
+  Return<void> selectTxPowerScenario(
+      TxPowerScenario scenario,
+      selectTxPowerScenario_cb hidl_status_cb) override;
+  Return<void> resetTxPowerScenario(
+      resetTxPowerScenario_cb hidl_status_cb) override;
 
  private:
   void invalidateAndRemoveAllIfaces();
@@ -180,8 +182,8 @@
   std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
   getDebugHostWakeReasonStatsInternal();
   WifiStatus enableDebugErrorAlertsInternal(bool enable);
-  WifiStatus setTxPowerLimitInternal(int32_t powerInDbm);
-  WifiStatus resetTxPowerLimitInternal();
+  WifiStatus selectTxPowerScenarioInternal(TxPowerScenario scenario);
+  WifiStatus resetTxPowerScenarioInternal();
 
   WifiStatus handleChipConfiguration(ChipModeId mode_id);
   WifiStatus registerDebugRingBufferCallback();
diff --git a/wifi/1.1/default/wifi_legacy_hal.cpp b/wifi/1.1/default/wifi_legacy_hal.cpp
index 052aafb..7d683d3 100644
--- a/wifi/1.1/default/wifi_legacy_hal.cpp
+++ b/wifi/1.1/default/wifi_legacy_hal.cpp
@@ -752,13 +752,13 @@
                                                       oui_internal.data());
 }
 
-wifi_error WifiLegacyHal::setTxPowerLimit(int32_t tx_level_dbm) {
-  return global_func_table_.wifi_set_tx_power_limit(wlan_interface_handle_,
-                                                    tx_level_dbm);
+wifi_error WifiLegacyHal::selectTxPowerScenario(wifi_power_scenario scenario) {
+  return global_func_table_.wifi_select_tx_power_scenario(
+      wlan_interface_handle_, scenario);
 }
 
-wifi_error WifiLegacyHal::resetTxPowerLimit() {
-  return global_func_table_.wifi_reset_tx_power_limit(wlan_interface_handle_);
+wifi_error WifiLegacyHal::resetTxPowerScenario() {
+  return global_func_table_.wifi_reset_tx_power_scenario(wlan_interface_handle_);
 }
 
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
diff --git a/wifi/1.1/default/wifi_legacy_hal.h b/wifi/1.1/default/wifi_legacy_hal.h
index 8d9144d..caa1bd5 100644
--- a/wifi/1.1/default/wifi_legacy_hal.h
+++ b/wifi/1.1/default/wifi_legacy_hal.h
@@ -205,8 +205,8 @@
       uint32_t period_in_ms);
   wifi_error stopSendingOffloadedPacket(uint32_t cmd_id);
   wifi_error setScanningMacOui(const std::array<uint8_t, 3>& oui);
-  wifi_error setTxPowerLimit(int32_t tx_level_dbm);
-  wifi_error resetTxPowerLimit();
+  wifi_error selectTxPowerScenario(wifi_power_scenario scenario);
+  wifi_error resetTxPowerScenario();
   // Logger/debug functions.
   std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
   wifi_error startPktFateMonitoring();
diff --git a/wifi/1.1/default/wifi_legacy_hal_stubs.cpp b/wifi/1.1/default/wifi_legacy_hal_stubs.cpp
index 24ed548..c02e3ba 100644
--- a/wifi/1.1/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.1/default/wifi_legacy_hal_stubs.cpp
@@ -132,8 +132,8 @@
   populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
   populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
   populateStubFor(&hal_fn->wifi_configure_roaming);
-  populateStubFor(&hal_fn->wifi_set_tx_power_limit);
-  populateStubFor(&hal_fn->wifi_reset_tx_power_limit);
+  populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
+  populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
   return true;
 }
 }  // namespace legacy_hal
diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
index 839b6c4..d3a983c 100644
--- a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp
@@ -37,7 +37,8 @@
 using ::android::hardware::wifi::V1_0::IWifiStaIface;
 
 namespace {
-constexpr int32_t kFakePowerInDbm = -56;
+constexpr IWifiChip::TxPowerScenario kFakePowerScenario =
+    IWifiChip::TxPowerScenario::VOICE_CALL;
 }; //namespace
 
 /**
@@ -66,12 +67,12 @@
 };
 
 /*
- * SetTxPowerLimit
+ * SelectTxPowerScenario
  */
-TEST_F(WifiChipHidlTest, SetTxPowerLimit) {
+TEST_F(WifiChipHidlTest, SelectTxPowerScenario) {
     uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
     const auto& status =
-        HIDL_INVOKE(wifi_chip_, setTxPowerLimit, kFakePowerInDbm);
+        HIDL_INVOKE(wifi_chip_, selectTxPowerScenario, kFakePowerScenario);
     if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
         EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
     } else {
@@ -80,12 +81,12 @@
 }
 
 /*
- * SetTxPowerLimit
+ * ResetTxPowerScenario
  */
-TEST_F(WifiChipHidlTest, ResetTxPowerLimit) {
+TEST_F(WifiChipHidlTest, ResetTxPowerScenario) {
     uint32_t caps = configureChipForStaIfaceAndGetCapabilities();
     const auto& status =
-        HIDL_INVOKE(wifi_chip_, resetTxPowerLimit);
+        HIDL_INVOKE(wifi_chip_, resetTxPowerScenario);
     if (caps & IWifiChip::ChipCapabilityMask::SET_TX_POWER_LIMIT) {
         EXPECT_EQ(WifiStatusCode::SUCCESS, status.code);
     } else {
diff --git a/wifi/Android.bp b/wifi/Android.bp
index b4ab98f..1153b0c 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -7,4 +7,5 @@
     "offload/1.0",
     "offload/1.0/vts/functional",
     "supplicant/1.0",
+    "supplicant/1.0/vts/functional",
 ]
diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp
index 28e8e6a..5b7fcad 100644
--- a/wifi/offload/1.0/Android.bp
+++ b/wifi/offload/1.0/Android.bp
@@ -46,13 +46,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.wifi.offload@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.wifi.offload@1.0_genc++"],
     generated_headers: ["android.hardware.wifi.offload@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.wifi.offload@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
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;
diff --git a/wifi/supplicant/1.0/Android.bp b/wifi/supplicant/1.0/Android.bp
index 9242fb6..978192d 100644
--- a/wifi/supplicant/1.0/Android.bp
+++ b/wifi/supplicant/1.0/Android.bp
@@ -116,13 +116,16 @@
     ],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.wifi.supplicant@1.0",
     defaults: ["hidl-module-defaults"],
     generated_sources: ["android.hardware.wifi.supplicant@1.0_genc++"],
     generated_headers: ["android.hardware.wifi.supplicant@1.0_genc++_headers"],
     export_generated_headers: ["android.hardware.wifi.supplicant@1.0_genc++_headers"],
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
     shared_libs: [
         "libhidlbase",
         "libhidltransport",
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..24b9f6f
--- /dev/null
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalWifiSupplicantV1_0TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "VtsHalWifiSupplicantV1_0TargetTest.cpp",
+        "supplicant_hidl_test.cpp",
+        "supplicant_hidl_test_utils.cpp",
+        "supplicant_p2p_iface_hidl_test.cpp",
+        "supplicant_sta_iface_hidl_test.cpp",
+        "supplicant_sta_network_hidl_test.cpp",
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi.supplicant@1.0",
+        "android.hardware.wifi@1.0",
+        "libcrypto",
+        "libgmock",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+}
diff --git a/wifi/supplicant/1.0/vts/functional/Android.mk b/wifi/supplicant/1.0/vts/functional/Android.mk
deleted file mode 100644
index c6e3950..0000000
--- a/wifi/supplicant/1.0/vts/functional/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := VtsHalWifiSupplicantV1_0TargetTest
-LOCAL_CPPFLAGS := -Wall -Werror -Wextra
-LOCAL_SRC_FILES := \
-    VtsHalWifiSupplicantV1_0TargetTest.cpp \
-    supplicant_hidl_test.cpp \
-    supplicant_hidl_test_utils.cpp \
-    supplicant_p2p_iface_hidl_test.cpp \
-    supplicant_sta_iface_hidl_test.cpp \
-    supplicant_sta_network_hidl_test.cpp
-LOCAL_SHARED_LIBRARIES := \
-    android.hardware.wifi.supplicant@1.0 \
-    android.hardware.wifi@1.0 \
-    libbase \
-    libcutils \
-    libhidlbase \
-    libhidltransport \
-    liblog \
-    libutils \
-    libwifi-system \
-    libwifi-system-iface
-LOCAL_STATIC_LIBRARIES := \
-    libgmock \
-    VtsHalHidlTargetTestBase \
-    VtsHalWifiV1_0TargetTestUtil
-include $(BUILD_NATIVE_TEST)
-