Merge "ConfirmationUI VTS tests"
diff --git a/audio/4.0/IDevice.hal b/audio/4.0/IDevice.hal
index bb58568..7eb03c8 100644
--- a/audio/4.0/IDevice.hal
+++ b/audio/4.0/IDevice.hal
@@ -268,4 +268,16 @@
      */
     getMicrophones()
          generates(Result retval, vec<MicrophoneInfo> microphones);
+
+    /**
+     * Notifies the device module about the connection state of an input/output
+     * device attached to it. Calling this method is equivalent to setting
+     * AUDIO_PARAMETER_DEVICE_[DIS]CONNECT on the legacy HAL.
+     *
+     * @param address audio device specification.
+     * @param connected whether the device is connected.
+     * @return retval operation completion status.
+     */
+    setConnectedState(DeviceAddress address, bool connected)
+            generates (Result retval);
 };
diff --git a/audio/4.0/IPrimaryDevice.hal b/audio/4.0/IPrimaryDevice.hal
index f3d904c..258c28b 100644
--- a/audio/4.0/IPrimaryDevice.hal
+++ b/audio/4.0/IPrimaryDevice.hal
@@ -37,6 +37,17 @@
     setMode(AudioMode mode) generates (Result retval);
 
     /**
+     * Sets the name of the current BT SCO headset. Calling this method
+     * is equivalent to setting legacy "bt_headset_name" parameter.
+     * The BT SCO headset name must only be used for debugging purposes.
+     * Optional method
+     *
+     * @param name the name of the current BT SCO headset (can be empty).
+     * @return retval operation completion status.
+     */
+    setBtScoHeadsetDebugName(string name) generates (Result retval);
+
+    /**
      * Gets whether BT SCO Noise Reduction and Echo Cancellation are enabled.
      * Calling this method is equivalent to getting AUDIO_PARAMETER_KEY_BT_NREC
      * on the legacy HAL.
@@ -76,6 +87,48 @@
      */
     setBtScoWidebandEnabled(bool enabled) generates (Result retval);
 
+    /**
+     * Gets whether BT HFP (Hands-Free Profile) is enabled. Calling this method
+     * is equivalent to getting "hfp_enable" parameter value on the legacy HAL.
+     *
+     * @return retval operation completion status.
+     * @return enabled whether BT HFP is enabled.
+     */
+    getBtHfpEnabled() generates (Result retval, bool enabled);
+
+    /**
+     * Sets whether BT HFP (Hands-Free Profile) is enabled. Calling this method
+     * is equivalent to setting "hfp_enable" parameter on the legacy HAL.
+     * Optional method
+     *
+     * @param enabled whether BT HFP is enabled.
+     * @return retval operation completion status.
+     */
+    setBtHfpEnabled(bool enabled) generates (Result retval);
+
+    /**
+     * Sets the sampling rate of BT HFP (Hands-Free Profile). Calling this
+     * method is equivalent to setting "hfp_set_sampling_rate" parameter
+     * on the legacy HAL.
+     * Optional method
+     *
+     * @param sampleRateHz sample rate in Hz.
+     * @return retval operation completion status.
+     */
+    setBtHfpSampleRate(uint32_t sampleRateHz) generates (Result retval);
+
+    /**
+     * Sets the current output volume Hz for BT HFP (Hands-Free Profile).
+     * Calling this method is equivalent to setting "hfp_volume" parameter value
+     * on the legacy HAL (except that legacy HAL implementations expect
+     * an integer value in the range from 0 to 15.)
+     * Optional method
+     *
+     * @param volume 1.0f means unity, 0.0f is zero.
+     * @return retval operation completion status.
+     */
+    setBtHfpVolume(float volume) generates (Result retval);
+
     enum TtyMode : int32_t {
         OFF,
         VCO,
@@ -121,4 +174,22 @@
      * @return retval operation completion status.
      */
     setHacEnabled(bool enabled) generates (Result retval);
+
+    enum Rotation : int32_t {
+        DEG_0,
+        DEG_90,
+        DEG_180,
+        DEG_270
+    };
+
+    /**
+     * Updates HAL on the current rotation of the device relative to natural
+     * orientation. Calling this method is equivalent to setting legacy
+     * parameter "rotation".
+     *
+     * @param rotation rotation in degrees relative to natural device
+     *     orientation.
+     * @return retval operation completion status.
+     */
+    updateRotation(Rotation rotation) generates (Result retval);
 };
diff --git a/audio/4.0/IStream.hal b/audio/4.0/IStream.hal
index f05d7b0..e7a4b7d 100644
--- a/audio/4.0/IStream.hal
+++ b/audio/4.0/IStream.hal
@@ -175,38 +175,26 @@
     standby() generates (Result retval);
 
     /**
-     * Return the set of device(s) which this stream is connected to.
+     * Return the set of devices which this stream is connected to.
      * Optional method
      *
      * @return retval operation completion status: OK or NOT_SUPPORTED.
-     * @return device set of device(s) which this stream is connected to.
+     * @return device set of devices which this stream is connected to.
      */
-    getDevice() generates (Result retval, bitfield<AudioDevice> device);
+    getDevices() generates (Result retval, vec<DeviceAddress> devices);
 
     /**
-     * Connects the stream to the device.
+     * Connects the stream to one or multiple devices.
      *
      * This method must only be used for HALs that do not support
      * 'IDevice.createAudioPatch' method. Calling this method is
-     * equivalent to setting AUDIO_PARAMETER_STREAM_ROUTING in the legacy HAL
-     * interface.
+     * equivalent to setting AUDIO_PARAMETER_STREAM_ROUTING preceeded
+     * with a device address in the legacy HAL interface.
      *
      * @param address device to connect the stream to.
      * @return retval operation completion status.
      */
-    setDevice(DeviceAddress address) generates (Result retval);
-
-    /**
-     * Notifies the stream about device connection state. Calling this method is
-     * equivalent to setting AUDIO_PARAMETER_DEVICE_[DIS]CONNECT on the legacy
-     * HAL.
-     *
-     * @param address audio device specification.
-     * @param connected whether the device is connected.
-     * @return retval operation completion status.
-     */
-    setConnectedState(DeviceAddress address, bool connected)
-            generates (Result retval);
+    setDevices(vec<DeviceAddress> devices) generates (Result retval);
 
     /**
      * Sets the HW synchronization source. Calling this method is equivalent to
diff --git a/audio/4.0/IStreamOut.hal b/audio/4.0/IStreamOut.hal
index 3aa93fc..65eba60 100644
--- a/audio/4.0/IStreamOut.hal
+++ b/audio/4.0/IStreamOut.hal
@@ -264,4 +264,16 @@
      */
     getPresentationPosition()
             generates (Result retval, uint64_t frames, TimeSpec timeStamp);
+
+    /**
+     * Selects a presentation for decoding from a next generation media stream
+     * (as defined per ETSI TS 103 190-2) and a program within the presentation.
+     * Optional method
+     *
+     * @param presentationId selected audio presentation.
+     * @param programId refinement for the presentation.
+     * @return retval operation completion status.
+     */
+    selectPresentation(int32_t presentationId, int32_t programId)
+            generates (Result retval);
 };
diff --git a/audio/4.0/types.hal b/audio/4.0/types.hal
index 7853f3c..7b2035b 100644
--- a/audio/4.0/types.hal
+++ b/audio/4.0/types.hal
@@ -23,6 +23,10 @@
     NOT_INITIALIZED,
     INVALID_ARGUMENTS,
     INVALID_STATE,
+    /**
+     * Methods marked as "Optional method" must return this result value
+     * if the operation is not supported by HAL.
+     */
     NOT_SUPPORTED
 };
 
diff --git a/audio/common/4.0/types.hal b/audio/common/4.0/types.hal
index d4c6efe..4efdea3 100644
--- a/audio/common/4.0/types.hal
+++ b/audio/common/4.0/types.hal
@@ -485,7 +485,7 @@
 };
 
 @export(name="", value_prefix="AUDIO_DEVICE_")
-enum AudioDevice : uint64_t {
+enum AudioDevice : uint32_t {
     NONE                          = 0x0,
     /** reserved bits */
     BIT_IN                        = 0x80000000,
@@ -530,6 +530,7 @@
     OUT_BUS                       = 0x1000000,
     OUT_PROXY                     = 0x2000000,
     OUT_USB_HEADSET               = 0x4000000,
+    OUT_HEARING_AID               = 0x8000000,
     OUT_ECHO_CANCELLER            = 0x10000000,
     OUT_DEFAULT                   = BIT_DEFAULT,
     // Note that the 2.0 OUT_ALL* have been moved to helper functions
diff --git a/authsecret/1.0/IAuthSecret.hal b/authsecret/1.0/IAuthSecret.hal
index 6b573b3..9a0fd5f 100644
--- a/authsecret/1.0/IAuthSecret.hal
+++ b/authsecret/1.0/IAuthSecret.hal
@@ -42,5 +42,5 @@
      *
      * @param secret blob derived from the primary user's credential.
      */
-    primaryUserCredential(vec<uint8_t> secret);
+    oneway primaryUserCredential(vec<uint8_t> secret);
 };
diff --git a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
index 57050d7..d904ad0 100644
--- a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
+++ b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
@@ -54,7 +54,7 @@
 #include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
 
 #include <VtsHalHidlTargetTestBase.h>
-
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 using namespace ::android::hardware::automotive::evs::V1_0;
 using ::android::hardware::Return;
@@ -64,13 +64,28 @@
 using ::android::hardware::hidl_string;
 using ::android::sp;
 
+// Test environment for Evs HIDL HAL.
+class EvsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static EvsHidlEnvironment* Instance() {
+        static EvsHidlEnvironment* instance = new EvsHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IEvsEnumerator>(); }
+
+   private:
+    EvsHidlEnvironment() {}
+};
 
 // The main test class for EVS
 class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
 public:
     virtual void SetUp() override {
         // Make sure we can connect to the enumerator
-        pEnumerator = IEvsEnumerator::getService(kEnumeratorName);
+        pEnumerator = getService<IEvsEnumerator>(
+            EvsHidlEnvironment::Instance()->getServiceName<IEvsEnumerator>(kEnumeratorName));
         ASSERT_NE(pEnumerator.get(), nullptr);
     }
 
@@ -480,3 +495,12 @@
     // Explicitly release the display
     pEnumerator->closeDisplay(pDisplay);
 }
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance());
+    ::testing::InitGoogleTest(&argc, argv);
+    EvsHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
+}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 7938b73..096500e 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -342,12 +342,6 @@
          },
      .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}},
 
-    {.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
-                .access = VehiclePropertyAccess::READ_WRITE,
-                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 10}}},
-     .initialValue = {.int32Values = {7}}},
-
     {.config =
          {
              .prop = toInt(VehicleProperty::IGNITION_STATE),
@@ -420,6 +414,23 @@
             },
     },
 
+    {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE),
+                .access = VehiclePropertyAccess::READ_WRITE,
+                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                .configArray = {3}},
+     .initialValue = {.int32Values = {toInt(VehicleApPowerState::ON_FULL), 0}}},
+
+    {.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
+                .access = VehiclePropertyAccess::READ_WRITE,
+                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 100}}},
+     .initialValue = {.int32Values = {100}}},
+
+    {.config = {.prop = toInt(VehicleProperty::AP_POWER_BOOTUP_REASON),
+                .access = VehiclePropertyAccess::READ,
+                .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
+     .initialValue = {.int32Values = {toInt(VehicleApPowerBootupReason::USER_POWER_ON)}}},
+
     {
         .config = {.prop = OBD2_LIVE_FRAME,
                    .access = VehiclePropertyAccess::READ,
diff --git a/broadcastradio/1.0/vts/functional/Android.bp b/broadcastradio/1.0/vts/functional/Android.bp
index f31a2dc..7040a01 100644
--- a/broadcastradio/1.0/vts/functional/Android.bp
+++ b/broadcastradio/1.0/vts/functional/Android.bp
@@ -18,5 +18,8 @@
     name: "VtsHalBroadcastradioV1_0TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalBroadcastradioV1_0TargetTest.cpp"],
-    static_libs: ["android.hardware.broadcastradio@1.0"],
+    static_libs: [
+        "android.hardware.broadcastradio@1.0",
+        "android.hardware.broadcastradio@vts-utils-lib",
+    ],
 }
diff --git a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
index fd048db..90c8463 100644
--- a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
+++ b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp
@@ -22,12 +22,12 @@
 #include <hidl/HidlTransportSupport.h>
 #include <utils/threads.h>
 
-#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
 #include <android/hardware/broadcastradio/1.0/IBroadcastRadio.h>
+#include <android/hardware/broadcastradio/1.0/IBroadcastRadioFactory.h>
 #include <android/hardware/broadcastradio/1.0/ITuner.h>
 #include <android/hardware/broadcastradio/1.0/ITunerCallback.h>
 #include <android/hardware/broadcastradio/1.0/types.h>
-
+#include <broadcastradio-vts-utils/environment-utils.h>
 
 using ::android::sp;
 using ::android::Mutex;
@@ -48,6 +48,7 @@
 using ::android::hardware::broadcastradio::V1_0::MetaData;
 using ::android::hardware::broadcastradio::V1_0::MetadataKey;
 using ::android::hardware::broadcastradio::V1_0::MetadataType;
+using ::android::hardware::broadcastradio::vts::BroadcastRadioHidlEnvironment;
 
 #define RETURN_IF_SKIPPED \
     if (skipped) { \
@@ -55,8 +56,8 @@
         return; \
     }
 
+static BroadcastRadioHidlEnvironment<IBroadcastRadioFactory>* gEnv = nullptr;
 // The main test class for Broadcast Radio HIDL HAL.
-
 class BroadcastRadioHidlTest : public ::testing::VtsHalHidlTargetTestBase,
         public ::testing::WithParamInterface<Class> {
  protected:
@@ -67,7 +68,7 @@
         skipped = false;
 
         sp<IBroadcastRadioFactory> factory =
-              ::testing::VtsHalHidlTargetTestBase::getService<IBroadcastRadioFactory>();
+            getService<IBroadcastRadioFactory>(gEnv->getServiceName<IBroadcastRadioFactory>());
         ASSERT_NE(nullptr, factory.get());
 
         Result connectResult;
@@ -731,8 +732,11 @@
     ::testing::Values(Class::AM_FM, Class::SAT, Class::DT));
 
 int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  int status = RUN_ALL_TESTS();
-  ALOGI("Test result = %d", status);
-  return status;
+    gEnv = new BroadcastRadioHidlEnvironment<IBroadcastRadioFactory>;
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
 }
diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
index 823d14c..6687731 100644
--- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
+++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp
@@ -25,6 +25,7 @@
 #include <android/hardware/broadcastradio/1.1/types.h>
 #include <broadcastradio-utils-1x/Utils.h>
 #include <broadcastradio-vts-utils/call-barrier.h>
+#include <broadcastradio-vts-utils/environment-utils.h>
 #include <broadcastradio-vts-utils/mock-timeout.h>
 #include <broadcastradio-vts-utils/pointer-utils.h>
 #include <cutils/native_handle.h>
@@ -58,6 +59,7 @@
 using V1_0::MetadataType;
 
 using broadcastradio::vts::clearAndWait;
+using broadcastradio::vts::BroadcastRadioHidlEnvironment;
 
 static constexpr auto kConfigTimeout = 10s;
 static constexpr auto kConnectModuleTimeout = 1s;
@@ -91,6 +93,8 @@
     MOCK_TIMEOUT_METHOD1(currentProgramInfoChanged, Return<void>(const ProgramInfo&));
 };
 
+static BroadcastRadioHidlEnvironment<IBroadcastRadioFactory>* gEnv = nullptr;
+
 class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase,
                               public ::testing::WithParamInterface<Class> {
    protected:
@@ -119,7 +123,8 @@
     radioClass = GetParam();
 
     // lookup HIDL service
-    auto factory = getService<IBroadcastRadioFactory>();
+    auto factory =
+        getService<IBroadcastRadioFactory>(gEnv->getServiceName<IBroadcastRadioFactory>());
     ASSERT_NE(nullptr, factory.get());
 
     // connect radio module
@@ -606,8 +611,14 @@
 }  // namespace android
 
 int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  int status = RUN_ALL_TESTS();
-  ALOGI("Test result = %d", status);
-  return status;
+    using android::hardware::broadcastradio::V1_1::vts::gEnv;
+    using android::hardware::broadcastradio::V1_1::IBroadcastRadioFactory;
+    using android::hardware::broadcastradio::vts::BroadcastRadioHidlEnvironment;
+    gEnv = new BroadcastRadioHidlEnvironment<IBroadcastRadioFactory>;
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
 }
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 2a5ec8fe..6877f07 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -26,6 +26,7 @@
 #include <android/hardware/broadcastradio/2.0/types.h>
 #include <broadcastradio-utils-2x/Utils.h>
 #include <broadcastradio-vts-utils/call-barrier.h>
+#include <broadcastradio-vts-utils/environment-utils.h>
 #include <broadcastradio-vts-utils/mock-timeout.h>
 #include <broadcastradio-vts-utils/pointer-utils.h>
 #include <cutils/bitops.h>
@@ -52,6 +53,7 @@
 using testing::Invoke;
 using testing::SaveArg;
 
+using broadcastradio::vts::BroadcastRadioHidlEnvironment;
 using broadcastradio::vts::CallBarrier;
 using broadcastradio::vts::clearAndWait;
 using utils::make_identifier;
@@ -97,6 +99,8 @@
     MOCK_METHOD1(onListUpdated, Return<void>(const hidl_vec<Announcement>&));
 };
 
+static BroadcastRadioHidlEnvironment<IBroadcastRadio>* gEnv = nullptr;
+
 class BroadcastRadioHalTest : public ::testing::VtsHalHidlTargetTestBase {
    protected:
     virtual void SetUp() override;
@@ -171,7 +175,7 @@
     EXPECT_EQ(nullptr, mModule.get()) << "Module is already open";
 
     // lookup HIDL service (radio module)
-    mModule = getService<IBroadcastRadio>();
+    mModule = getService<IBroadcastRadio>(gEnv->getServiceName<IBroadcastRadio>());
     ASSERT_NE(nullptr, mModule.get()) << "Couldn't find broadcast radio HAL implementation";
 
     // get module properties
@@ -804,7 +808,13 @@
 }  // namespace android
 
 int main(int argc, char** argv) {
+    using android::hardware::broadcastradio::V2_0::vts::gEnv;
+    using android::hardware::broadcastradio::V2_0::IBroadcastRadio;
+    using android::hardware::broadcastradio::vts::BroadcastRadioHidlEnvironment;
+    gEnv = new BroadcastRadioHidlEnvironment<IBroadcastRadio>;
+    ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     ALOGI("Test result = %d", status);
     return status;
diff --git a/broadcastradio/common/vts/utils/Android.bp b/broadcastradio/common/vts/utils/Android.bp
index 4ba8a17..d3edc76 100644
--- a/broadcastradio/common/vts/utils/Android.bp
+++ b/broadcastradio/common/vts/utils/Android.bp
@@ -25,4 +25,8 @@
         "-Wextra",
         "-Werror",
     ],
+    static_libs: [
+        "VtsHalHidlTargetTestBase",
+    ],
+    group_static_libs: true,
 }
diff --git a/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/environment-utils.h b/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/environment-utils.h
new file mode 100644
index 0000000..274e632
--- /dev/null
+++ b/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/environment-utils.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_HARDWARE_BROADCASTRADIO_VTS_ENVIRONMENT_UTILS
+#define ANDROID_HARDWARE_BROADCASTRADIO_VTS_ENVIRONMENT_UTILS
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+namespace android {
+namespace hardware {
+namespace broadcastradio {
+namespace vts {
+
+// Test environment for BroadcastRadio HIDL HAL.
+template <typename... T>
+class BroadcastRadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    virtual void registerTestServices() override {
+        using expander = int[];
+        (void)expander{0, (registerTestService<T>(), 0)...};
+    }
+};
+
+}  // namespace vts
+}  // namespace broadcastradio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_BROADCASTRADIO_VTS_ENVIRONMENT_UTILS
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index 771197a..bb4886d 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -370,7 +370,7 @@
 
         for (size_t i = 0; i < settingsCount; i++) {
             uint64_t settingsSize = request.physicalCameraSettings[i].fmqSettingsSize;
-            const camera_metadata_t *settings;
+            const camera_metadata_t *settings = nullptr;
             if (settingsSize > 0) {
                 physicalFmq.push_back(V3_2::CameraMetadata(settingsSize));
                 bool read = mRequestMetadataQueue->read(physicalFmq[i].data(), settingsSize);
@@ -392,6 +392,13 @@
                 ALOGE("%s: physical camera settings metadata is corrupt!", __FUNCTION__);
                 return Status::ILLEGAL_ARGUMENT;
             }
+
+            if (mFirstRequest && settings == nullptr) {
+                ALOGE("%s: Individual request settings must not be null for first request!",
+                        __FUNCTION__);
+                return Status::ILLEGAL_ARGUMENT;
+            }
+
             physicalCameraIds.push_back(request.physicalCameraSettings[i].physicalCameraId.c_str());
         }
     }
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 61b8921..14f82bc 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -131,7 +131,7 @@
 
     session = new ExternalCameraDeviceSession(
             callback, mCfg, mSupportedFormats, mCroppingType,
-            mCameraCharacteristics, std::move(fd));
+            mCameraCharacteristics, mCameraId, std::move(fd));
     if (session == nullptr) {
         ALOGE("%s: camera device session allocation failed", __FUNCTION__);
         mLock.unlock();
@@ -595,16 +595,19 @@
                     ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
         }
 
-        int64_t min_frame_duration = std::numeric_limits<int64_t>::max();
-        for (const auto& frameRate : supportedFormat.frameRates) {
-            int64_t frame_duration = 1000000000LL / frameRate;
-            if (frame_duration < min_frame_duration) {
-                min_frame_duration = frame_duration;
+        int64_t minFrameDuration = std::numeric_limits<int64_t>::max();
+        for (const auto& fr : supportedFormat.frameRates) {
+            // 1000000000LL < (2^32 - 1) and
+            // fr.durationNumerator is uint32_t, so no overflow here
+            int64_t frameDuration = 1000000000LL * fr.durationNumerator /
+                    fr.durationDenominator;
+            if (frameDuration < minFrameDuration) {
+                minFrameDuration = frameDuration;
             }
-            if (frame_duration > maxFrameDuration) {
-                maxFrameDuration = frame_duration;
+            if (frameDuration > maxFrameDuration) {
+                maxFrameDuration = frameDuration;
             }
-            int32_t frameRateInt = static_cast<int32_t>(frameRate);
+            int32_t frameRateInt = static_cast<int32_t>(fr.getDouble());
             if (minFps > frameRateInt) {
                 minFps = frameRateInt;
             }
@@ -618,7 +621,7 @@
             minFrameDurations.push_back(format);
             minFrameDurations.push_back(supportedFormat.width);
             minFrameDurations.push_back(supportedFormat.height);
-            minFrameDurations.push_back(min_frame_duration);
+            minFrameDurations.push_back(minFrameDuration);
         }
 
         // The stall duration is 0 for non-jpeg formats. For JPEG format, stall
@@ -705,8 +708,10 @@
             ++frameInterval.index) {
         if (frameInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
             if (frameInterval.discrete.numerator != 0) {
-                float framerate = frameInterval.discrete.denominator /
-                        static_cast<float>(frameInterval.discrete.numerator);
+                SupportedV4L2Format::FrameRate fr = {
+                        frameInterval.discrete.numerator,
+                        frameInterval.discrete.denominator};
+                double framerate = fr.getDouble();
                 if (framerate > fpsUpperBound) {
                     continue;
                 }
@@ -717,7 +722,7 @@
                     (frameInterval.pixel_format >> 16) & 0xFF,
                     (frameInterval.pixel_format >> 24) & 0xFF,
                     frameInterval.width, frameInterval.height, framerate);
-                format->frameRates.push_back(framerate);
+                format->frameRates.push_back(fr);
             }
         }
     }
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index b6728ed..5346f80 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -46,6 +46,21 @@
                                        // bad frames. TODO: develop a better bad frame detection
                                        // method
 
+bool tryLock(Mutex& mutex)
+{
+    static const int kDumpLockRetries = 50;
+    static const int kDumpLockSleep = 60000;
+    bool locked = false;
+    for (int i = 0; i < kDumpLockRetries; ++i) {
+        if (mutex.tryLock() == NO_ERROR) {
+            locked = true;
+            break;
+        }
+        usleep(kDumpLockSleep);
+    }
+    return locked;
+}
+
 } // Anonymous namespace
 
 // Static instances
@@ -59,12 +74,14 @@
         const std::vector<SupportedV4L2Format>& sortedFormats,
         const CroppingType& croppingType,
         const common::V1_0::helper::CameraMetadata& chars,
+        const std::string& cameraId,
         unique_fd v4l2Fd) :
         mCallback(callback),
         mCfg(cfg),
         mCameraCharacteristics(chars),
         mSupportedFormats(sortedFormats),
         mCroppingType(croppingType),
+        mCameraId(cameraId),
         mV4l2Fd(std::move(v4l2Fd)),
         mOutputThread(new OutputThread(this, mCroppingType)),
         mMaxThumbResolution(getMaxThumbResolution()),
@@ -119,8 +136,79 @@
     }
 }
 
-void ExternalCameraDeviceSession::dumpState(const native_handle_t*) {
-    // TODO: b/72261676 dump more runtime information
+
+void ExternalCameraDeviceSession::dumpState(const native_handle_t* handle) {
+    if (handle->numFds != 1 || handle->numInts != 0) {
+        ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints",
+                __FUNCTION__, handle->numFds, handle->numInts);
+        return;
+    }
+    int fd = handle->data[0];
+
+    bool intfLocked = tryLock(mInterfaceLock);
+    if (!intfLocked) {
+        dprintf(fd, "!! ExternalCameraDeviceSession interface may be deadlocked !!\n");
+    }
+
+    if (isClosed()) {
+        dprintf(fd, "External camera %s is closed\n", mCameraId.c_str());
+        return;
+    }
+
+    bool streaming = false;
+    size_t v4L2BufferCount = 0;
+    SupportedV4L2Format streamingFmt;
+    std::unordered_set<uint32_t>  inflightFrames;
+    {
+        Mutex::Autolock _l(mLock);
+        bool sessionLocked = tryLock(mLock);
+        if (!sessionLocked) {
+            dprintf(fd, "!! ExternalCameraDeviceSession mLock may be deadlocked !!\n");
+        }
+        streaming = mV4l2Streaming;
+        streamingFmt = mV4l2StreamingFmt;
+        v4L2BufferCount = mV4L2BufferCount;
+        inflightFrames = mInflightFrames;
+        if (sessionLocked) {
+            mLock.unlock();
+        }
+    }
+
+    dprintf(fd, "External camera %s V4L2 FD %d, cropping type %s, %s\n",
+            mCameraId.c_str(), mV4l2Fd.get(),
+            (mCroppingType == VERTICAL) ? "vertical" : "horizontal",
+            streaming ? "streaming" : "not streaming");
+    if (streaming) {
+        // TODO: dump fps later
+        dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d\n",
+                streamingFmt.fourcc & 0xFF,
+                (streamingFmt.fourcc >> 8) & 0xFF,
+                (streamingFmt.fourcc >> 16) & 0xFF,
+                (streamingFmt.fourcc >> 24) & 0xFF,
+                streamingFmt.width, streamingFmt.height);
+
+        size_t numDequeuedV4l2Buffers = 0;
+        {
+            std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+            numDequeuedV4l2Buffers = mNumDequeuedV4l2Buffers;
+        }
+        dprintf(fd, "V4L2 buffer queue size %zu, dequeued %zu\n",
+                v4L2BufferCount, numDequeuedV4l2Buffers);
+    }
+
+    dprintf(fd, "In-flight frames (not sorted):");
+    for (const auto& frameNumber : inflightFrames) {
+        dprintf(fd, "%d, ", frameNumber);
+    }
+    dprintf(fd, "\n");
+    mOutputThread->dump(fd);
+    dprintf(fd, "\n");
+
+    if (intfLocked) {
+        mInterfaceLock.unlock();
+    }
+
+    return;
 }
 
 Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings(
@@ -270,26 +358,31 @@
 }
 
 Return<Status> ExternalCameraDeviceSession::flush() {
+    Mutex::Autolock _il(mInterfaceLock);
+    Status status = initStatus();
+    if (status != Status::OK) {
+        return status;
+    }
+    mOutputThread->flush();
     return Status::OK;
 }
 
 Return<void> ExternalCameraDeviceSession::close() {
     Mutex::Autolock _il(mInterfaceLock);
-    Mutex::Autolock _l(mLock);
-    if (!mClosed) {
-        // TODO: b/72261676 Cleanup inflight buffers/V4L2 buffer queue
+    bool closed = isClosed();
+    if (!closed) {
+        mOutputThread->flush();
+        mOutputThread->requestExit();
+        mOutputThread->join();
+
+        Mutex::Autolock _l(mLock);
+        // free all buffers
+        for(auto pair : mStreamMap) {
+            cleanupBuffersLocked(/*Stream ID*/pair.first);
+        }
+        v4l2StreamOffLocked();
         ALOGV("%s: closing V4L2 camera FD %d", __FUNCTION__, mV4l2Fd.get());
         mV4l2Fd.reset();
-        mOutputThread->requestExit(); // TODO: join?
-
-        // free all imported buffers
-        for(auto& pair : mCirculatingBuffers) {
-            CirculatingBuffers& buffers = pair.second;
-            for (auto& p2 : buffers) {
-                sHandleImporter.freeBuffer(p2.second);
-            }
-        }
-
         mClosed = true;
     }
     return Void();
@@ -425,25 +518,22 @@
     // TODO: program fps range per capture request here
     //       or limit the set of availableFpsRange
 
-    sp<V4L2Frame> frameIn = dequeueV4l2FrameLocked();
+
+    nsecs_t shutterTs = 0;
+    sp<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
     if ( frameIn == nullptr) {
         ALOGE("%s: V4L2 deque frame failed!", __FUNCTION__);
         return Status::INTERNAL_ERROR;
     }
-    // TODO: This can probably be replaced by use v4lbuffer timestamp
-    //       if the device supports it
-    nsecs_t shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
 
-
-    // TODO: reduce object copy in this path
-    HalRequest halReq = {
-            .frameNumber = request.frameNumber,
-            .setting = mLatestReqSetting,
-            .frameIn = frameIn,
-            .shutterTs = shutterTs};
-    halReq.buffers.resize(numOutputBufs);
+    std::shared_ptr<HalRequest> halReq = std::make_shared<HalRequest>();
+    halReq->frameNumber = request.frameNumber;
+    halReq->setting = mLatestReqSetting;
+    halReq->frameIn = frameIn;
+    halReq->shutterTs = shutterTs;
+    halReq->buffers.resize(numOutputBufs);
     for (size_t i = 0; i < numOutputBufs; i++) {
-        HalStreamBuffer& halBuf = halReq.buffers[i];
+        HalStreamBuffer& halBuf = halReq->buffers[i];
         int streamId = halBuf.streamId = request.outputBuffers[i].streamId;
         halBuf.bufferId = request.outputBuffers[i].bufferId;
         const Stream& stream = mStreamMap[streamId];
@@ -455,7 +545,7 @@
         halBuf.acquireFence = allFences[i];
         halBuf.fenceTimeout = false;
     }
-    mInflightFrames.insert(halReq.frameNumber);
+    mInflightFrames.insert(halReq->frameNumber);
     // Send request to OutputThread for the rest of processing
     mOutputThread->submitRequest(halReq);
     mFirstRequest = false;
@@ -481,30 +571,31 @@
 }
 
 //TODO: refactor with processCaptureResult
-Status ExternalCameraDeviceSession::processCaptureRequestError(HalRequest& req) {
+Status ExternalCameraDeviceSession::processCaptureRequestError(
+        const std::shared_ptr<HalRequest>& req) {
     // Return V4L2 buffer to V4L2 buffer queue
-    enqueueV4l2Frame(req.frameIn);
+    enqueueV4l2Frame(req->frameIn);
 
     // NotifyShutter
-    notifyShutter(req.frameNumber, req.shutterTs);
+    notifyShutter(req->frameNumber, req->shutterTs);
 
-    notifyError(/*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_REQUEST);
+    notifyError(/*frameNum*/req->frameNumber, /*stream*/-1, ErrorCode::ERROR_REQUEST);
 
     // Fill output buffers
     hidl_vec<CaptureResult> results;
     results.resize(1);
     CaptureResult& result = results[0];
-    result.frameNumber = req.frameNumber;
+    result.frameNumber = req->frameNumber;
     result.partialResult = 1;
     result.inputBuffer.streamId = -1;
-    result.outputBuffers.resize(req.buffers.size());
-    for (size_t i = 0; i < req.buffers.size(); i++) {
-        result.outputBuffers[i].streamId = req.buffers[i].streamId;
-        result.outputBuffers[i].bufferId = req.buffers[i].bufferId;
+    result.outputBuffers.resize(req->buffers.size());
+    for (size_t i = 0; i < req->buffers.size(); i++) {
+        result.outputBuffers[i].streamId = req->buffers[i].streamId;
+        result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
         result.outputBuffers[i].status = BufferStatus::ERROR;
-        if (req.buffers[i].acquireFence >= 0) {
+        if (req->buffers[i].acquireFence >= 0) {
             native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
-            handle->data[0] = req.buffers[i].acquireFence;
+            handle->data[0] = req->buffers[i].acquireFence;
             result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
         }
     }
@@ -512,7 +603,7 @@
     // update inflight records
     {
         Mutex::Autolock _l(mLock);
-        mInflightFrames.erase(req.frameNumber);
+        mInflightFrames.erase(req->frameNumber);
     }
 
     // Callback into framework
@@ -521,51 +612,51 @@
     return Status::OK;
 }
 
-Status ExternalCameraDeviceSession::processCaptureResult(HalRequest& req) {
+Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
     // Return V4L2 buffer to V4L2 buffer queue
-    enqueueV4l2Frame(req.frameIn);
+    enqueueV4l2Frame(req->frameIn);
 
     // NotifyShutter
-    notifyShutter(req.frameNumber, req.shutterTs);
+    notifyShutter(req->frameNumber, req->shutterTs);
 
     // Fill output buffers
     hidl_vec<CaptureResult> results;
     results.resize(1);
     CaptureResult& result = results[0];
-    result.frameNumber = req.frameNumber;
+    result.frameNumber = req->frameNumber;
     result.partialResult = 1;
     result.inputBuffer.streamId = -1;
-    result.outputBuffers.resize(req.buffers.size());
-    for (size_t i = 0; i < req.buffers.size(); i++) {
-        result.outputBuffers[i].streamId = req.buffers[i].streamId;
-        result.outputBuffers[i].bufferId = req.buffers[i].bufferId;
-        if (req.buffers[i].fenceTimeout) {
+    result.outputBuffers.resize(req->buffers.size());
+    for (size_t i = 0; i < req->buffers.size(); i++) {
+        result.outputBuffers[i].streamId = req->buffers[i].streamId;
+        result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
+        if (req->buffers[i].fenceTimeout) {
             result.outputBuffers[i].status = BufferStatus::ERROR;
             native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
-            handle->data[0] = req.buffers[i].acquireFence;
+            handle->data[0] = req->buffers[i].acquireFence;
             result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
-            notifyError(req.frameNumber, req.buffers[i].streamId, ErrorCode::ERROR_BUFFER);
+            notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
         } else {
             result.outputBuffers[i].status = BufferStatus::OK;
             // TODO: refactor
-            if (req.buffers[i].acquireFence > 0) {
+            if (req->buffers[i].acquireFence > 0) {
                 native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
-                handle->data[0] = req.buffers[i].acquireFence;
+                handle->data[0] = req->buffers[i].acquireFence;
                 result.outputBuffers[i].releaseFence.setTo(handle, /*shouldOwn*/false);
             }
         }
     }
 
     // Fill capture result metadata
-    fillCaptureResult(req.setting, req.shutterTs);
-    const camera_metadata_t *rawResult = req.setting.getAndLock();
+    fillCaptureResult(req->setting, req->shutterTs);
+    const camera_metadata_t *rawResult = req->setting.getAndLock();
     V3_2::implementation::convertToHidl(rawResult, &result.result);
-    req.setting.unlock(rawResult);
+    req->setting.unlock(rawResult);
 
     // update inflight records
     {
         Mutex::Autolock _l(mLock);
-        mInflightFrames.erase(req.frameNumber);
+        mInflightFrames.erase(req->frameNumber);
     }
 
     // Callback into framework
@@ -1296,7 +1387,7 @@
 
 int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
         HalStreamBuffer &halBuf,
-        HalRequest &req)
+        const std::shared_ptr<HalRequest>& req)
 {
     int ret;
     auto lfail = [&](auto... args) {
@@ -1323,17 +1414,17 @@
     int jpegQuality, thumbQuality;
     Size thumbSize;
 
-    if (req.setting.exists(ANDROID_JPEG_QUALITY)) {
+    if (req->setting.exists(ANDROID_JPEG_QUALITY)) {
         camera_metadata_entry entry =
-            req.setting.find(ANDROID_JPEG_QUALITY);
+            req->setting.find(ANDROID_JPEG_QUALITY);
         jpegQuality = entry.data.u8[0];
     } else {
         return lfail("%s: ANDROID_JPEG_QUALITY not set",__FUNCTION__);
     }
 
-    if (req.setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
+    if (req->setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
         camera_metadata_entry entry =
-            req.setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY);
+            req->setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY);
         thumbQuality = entry.data.u8[0];
     } else {
         return lfail(
@@ -1341,9 +1432,9 @@
             __FUNCTION__);
     }
 
-    if (req.setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
+    if (req->setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
         camera_metadata_entry entry =
-            req.setting.find(ANDROID_JPEG_THUMBNAIL_SIZE);
+            req->setting.find(ANDROID_JPEG_THUMBNAIL_SIZE);
         thumbSize = Size { static_cast<uint32_t>(entry.data.i32[0]),
                            static_cast<uint32_t>(entry.data.i32[1])
         };
@@ -1403,7 +1494,7 @@
     /* Combine camera characteristics with request settings to form EXIF
      * metadata */
     common::V1_0::helper::CameraMetadata meta(parent->mCameraCharacteristics);
-    meta.append(req.setting);
+    meta.append(req->setting);
 
     /* Generate EXIF object */
     std::unique_ptr<ExifUtils> utils(ExifUtils::create());
@@ -1467,7 +1558,7 @@
 }
 
 bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
-    HalRequest req;
+    std::shared_ptr<HalRequest> req;
     auto parent = mParent.promote();
     if (parent == nullptr) {
        ALOGE("%s: session has been disconnected!", __FUNCTION__);
@@ -1478,29 +1569,33 @@
     //       regularly to prevent v4l buffer queue filled with stale buffers
     //       when app doesn't program a preveiw request
     waitForNextRequest(&req);
-    if (req.frameIn == nullptr) {
+    if (req == nullptr) {
         // No new request, wait again
         return true;
     }
 
-    if (req.frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) {
-        ALOGE("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
-                req.frameIn->mFourcc & 0xFF,
-                (req.frameIn->mFourcc >> 8) & 0xFF,
-                (req.frameIn->mFourcc >> 16) & 0xFF,
-                (req.frameIn->mFourcc >> 24) & 0xFF);
+    auto onDeviceError = [&](auto... args) {
+        ALOGE(args...);
         parent->notifyError(
-                /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
+                req->frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
+        signalRequestDone();
         return false;
+    };
+
+    if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG) {
+        return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
+                req->frameIn->mFourcc & 0xFF,
+                (req->frameIn->mFourcc >> 8) & 0xFF,
+                (req->frameIn->mFourcc >> 16) & 0xFF,
+                (req->frameIn->mFourcc >> 24) & 0xFF);
     }
 
-    std::unique_lock<std::mutex> lk(mLock);
-
+    std::unique_lock<std::mutex> lk(mBufferLock);
     // Convert input V4L2 frame to YU12 of the same size
     // TODO: see if we can save some computation by converting to YV12 here
     uint8_t* inData;
     size_t inDataSize;
-    req.frameIn->map(&inData, &inDataSize);
+    req->frameIn->map(&inData, &inDataSize);
     // TODO: profile
     // TODO: in some special case maybe we can decode jpg directly to gralloc output?
     int res = libyuv::MJPGToI420(
@@ -1520,17 +1615,15 @@
         lk.unlock();
         Status st = parent->processCaptureRequestError(req);
         if (st != Status::OK) {
-            ALOGE("%s: failed to process capture request error!", __FUNCTION__);
-            parent->notifyError(
-                    /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-            return false;
+            return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
         }
+        signalRequestDone();
         return true;
     }
 
     ALOGV("%s processing new request", __FUNCTION__);
     const int kSyncWaitTimeoutMs = 500;
-    for (auto& halBuf : req.buffers) {
+    for (auto& halBuf : req->buffers) {
         if (halBuf.acquireFence != -1) {
             int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
             if (ret) {
@@ -1551,15 +1644,9 @@
                 int ret = createJpegLocked(halBuf, req);
 
                 if(ret != 0) {
-                    ALOGE("%s: createJpegLocked failed with %d",
-                          __FUNCTION__, ret);
                     lk.unlock();
-                    parent->notifyError(
-                            /*frameNum*/req.frameNumber,
-                            /*stream*/-1,
-                            ErrorCode::ERROR_DEVICE);
-
-                    return false;
+                    return onDeviceError("%s: createJpegLocked failed with %d",
+                          __FUNCTION__, ret);
                 }
             } break;
             case PixelFormat::YCBCR_420_888:
@@ -1587,21 +1674,15 @@
                         Size { halBuf.width, halBuf.height },
                         &cropAndScaled);
                 if (ret != 0) {
-                    ALOGE("%s: crop and scale failed!", __FUNCTION__);
                     lk.unlock();
-                    parent->notifyError(
-                            /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-                    return false;
+                    return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
                 }
 
                 Size sz {halBuf.width, halBuf.height};
                 ret = formatConvertLocked(cropAndScaled, outLayout, sz, outputFourcc);
                 if (ret != 0) {
-                    ALOGE("%s: format coversion failed!", __FUNCTION__);
                     lk.unlock();
-                    parent->notifyError(
-                            /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-                    return false;
+                    return onDeviceError("%s: format coversion failed!", __FUNCTION__);
                 }
                 int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
                 if (relFence > 0) {
@@ -1609,11 +1690,8 @@
                 }
             } break;
             default:
-                ALOGE("%s: unknown output format %x", __FUNCTION__, halBuf.format);
                 lk.unlock();
-                parent->notifyError(
-                        /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-                return false;
+                return onDeviceError("%s: unknown output format %x", __FUNCTION__, halBuf.format);
         }
     } // for each buffer
     mScaledYu12Frames.clear();
@@ -1622,18 +1700,16 @@
     lk.unlock();
     Status st = parent->processCaptureResult(req);
     if (st != Status::OK) {
-        ALOGE("%s: failed to process capture result!", __FUNCTION__);
-        parent->notifyError(
-                /*frameNum*/req.frameNumber, /*stream*/-1, ErrorCode::ERROR_DEVICE);
-        return false;
+        return onDeviceError("%s: failed to process capture result!", __FUNCTION__);
     }
+    signalRequestDone();
     return true;
 }
 
 Status ExternalCameraDeviceSession::OutputThread::allocateIntermediateBuffers(
         const Size& v4lSize, const Size& thumbSize,
         const hidl_vec<Stream>& streams) {
-    std::lock_guard<std::mutex> lk(mLock);
+    std::lock_guard<std::mutex> lk(mBufferLock);
     if (mScaledYu12Frames.size() != 0) {
         ALOGE("%s: intermediate buffer pool has %zu inflight buffers! (expect 0)",
                 __FUNCTION__, mScaledYu12Frames.size());
@@ -1704,37 +1780,88 @@
     return Status::OK;
 }
 
-Status ExternalCameraDeviceSession::OutputThread::submitRequest(const HalRequest& req) {
-    std::lock_guard<std::mutex> lk(mLock);
-    // TODO: reduce object copy in this path
+Status ExternalCameraDeviceSession::OutputThread::submitRequest(
+        const std::shared_ptr<HalRequest>& req) {
+    std::unique_lock<std::mutex> lk(mRequestListLock);
     mRequestList.push_back(req);
+    lk.unlock();
     mRequestCond.notify_one();
     return Status::OK;
 }
 
 void ExternalCameraDeviceSession::OutputThread::flush() {
-    std::lock_guard<std::mutex> lk(mLock);
-    // TODO: send buffer/request errors back to framework
+    auto parent = mParent.promote();
+    if (parent == nullptr) {
+       ALOGE("%s: session has been disconnected!", __FUNCTION__);
+       return;
+    }
+
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList);
     mRequestList.clear();
+    if (mProcessingRequest) {
+        std::chrono::seconds timeout = std::chrono::seconds(kFlushWaitTimeoutSec);
+        auto st = mRequestDoneCond.wait_for(lk, timeout);
+        if (st == std::cv_status::timeout) {
+            ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
+        }
+    }
+
+    lk.unlock();
+    for (const auto& req : reqs) {
+        parent->processCaptureRequestError(req);
+    }
 }
 
-void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(HalRequest* out) {
+void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(
+        std::shared_ptr<HalRequest>* out) {
     if (out == nullptr) {
         ALOGE("%s: out is null", __FUNCTION__);
         return;
     }
 
-    std::unique_lock<std::mutex> lk(mLock);
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    int waitTimes = 0;
     while (mRequestList.empty()) {
-        std::chrono::seconds timeout = std::chrono::seconds(kReqWaitTimeoutSec);
+        if (exitPending()) {
+            return;
+        }
+        std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
         auto st = mRequestCond.wait_for(lk, timeout);
         if (st == std::cv_status::timeout) {
-            // no new request, return
-            return;
+            waitTimes++;
+            if (waitTimes == kReqWaitTimesMax) {
+                // no new request, return
+                return;
+            }
         }
     }
     *out = mRequestList.front();
     mRequestList.pop_front();
+    mProcessingRequest = true;
+    mProcessingFrameNumer = (*out)->frameNumber;
+}
+
+void ExternalCameraDeviceSession::OutputThread::signalRequestDone() {
+    std::unique_lock<std::mutex> lk(mRequestListLock);
+    mProcessingRequest = false;
+    mProcessingFrameNumer = 0;
+    lk.unlock();
+    mRequestDoneCond.notify_one();
+}
+
+void ExternalCameraDeviceSession::OutputThread::dump(int fd) {
+    std::lock_guard<std::mutex> lk(mRequestListLock);
+    if (mProcessingRequest) {
+        dprintf(fd, "OutputThread processing frame %d\n", mProcessingFrameNumer);
+    } else {
+        dprintf(fd, "OutputThread not processing any frames\n");
+    }
+    dprintf(fd, "OutputThread request list contains frame: ");
+    for (const auto& req : mRequestList) {
+        dprintf(fd, "%d, ", req->frameNumber);
+    }
+    dprintf(fd, "\n");
 }
 
 void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) {
@@ -1893,7 +2020,8 @@
     float fps = 1000.f;
     const float kDefaultFps = 30.f;
     // Try to pick the slowest fps that is at least 30
-    for (const auto& f : v4l2Fmt.frameRates) {
+    for (const auto& fr : v4l2Fmt.frameRates) {
+        double f = fr.getDouble();
         if (maxFps < f) {
             maxFps = f;
         }
@@ -1997,15 +2125,25 @@
     return OK;
 }
 
-sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked() {
+sp<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs) {
     sp<V4L2Frame> ret = nullptr;
 
+    if (shutterTs == nullptr) {
+        ALOGE("%s: shutterTs must not be null!", __FUNCTION__);
+        return ret;
+    }
+
     {
         std::unique_lock<std::mutex> lk(mV4l2BufferLock);
         if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
             std::chrono::seconds timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
             mLock.unlock();
             auto st = mV4L2BufferReturned.wait_for(lk, timeout);
+            // Here we introduce a case where mV4l2BufferLock is acquired before mLock, while
+            // the normal lock acquisition order is reversed, but this is fine because in most of
+            // cases we are protected by mInterfaceLock. The only thread that can compete these
+            // locks are the OutputThread, where we do need to make sure we don't acquire mLock then
+            // mV4l2BufferLock
             mLock.lock();
             if (st == std::cv_status::timeout) {
                 ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
@@ -2032,6 +2170,15 @@
         // TODO: try to dequeue again
     }
 
+    if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
+        // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
+        // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
+        *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec)*1000000000LL +
+                buffer.timestamp.tv_usec * 1000LL;
+    } else {
+        *shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
+    }
+
     {
         std::lock_guard<std::mutex> lk(mV4l2BufferLock);
         mNumDequeuedV4l2Buffers++;
@@ -2042,22 +2189,27 @@
 }
 
 void ExternalCameraDeviceSession::enqueueV4l2Frame(const sp<V4L2Frame>& frame) {
-    Mutex::Autolock _l(mLock);
-    frame->unmap();
-    v4l2_buffer buffer{};
-    buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    buffer.memory = V4L2_MEMORY_MMAP;
-    buffer.index = frame->mBufferIndex;
-    if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
-        ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__, frame->mBufferIndex, strerror(errno));
-        return;
+    {
+        // Release mLock before acquiring mV4l2BufferLock to avoid potential
+        // deadlock
+        Mutex::Autolock _l(mLock);
+        frame->unmap();
+        v4l2_buffer buffer{};
+        buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        buffer.memory = V4L2_MEMORY_MMAP;
+        buffer.index = frame->mBufferIndex;
+        if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+            ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__,
+                    frame->mBufferIndex, strerror(errno));
+            return;
+        }
     }
 
     {
         std::lock_guard<std::mutex> lk(mV4l2BufferLock);
         mNumDequeuedV4l2Buffers--;
-        mV4L2BufferReturned.notify_one();
     }
+    mV4L2BufferReturned.notify_one();
 }
 
 Status ExternalCameraDeviceSession::configureStreams(
@@ -2335,8 +2487,8 @@
     bool support30Fps = false;
     int32_t maxFps = std::numeric_limits<int32_t>::min();
     for (const auto& supportedFormat : mSupportedFormats) {
-        for (const auto& frameRate : supportedFormat.frameRates) {
-            int32_t framerateInt = static_cast<int32_t>(frameRate);
+        for (const auto& fr : supportedFormat.frameRates) {
+            int32_t framerateInt = static_cast<int32_t>(fr.getDouble());
             if (maxFps < framerateInt) {
                 maxFps = framerateInt;
             }
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 80f296c..d28a4dd 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -147,6 +147,10 @@
     return (std::abs(ar1 - ar2) < kAspectRatioMatchThres);
 }
 
+double SupportedV4L2Format::FrameRate::getDouble() const {
+    return durationDenominator / static_cast<double>(durationNumerator);
+}
+
 }  // namespace implementation
 }  // namespace V3_4
 }  // namespace device
@@ -247,7 +251,7 @@
             limit.size = {
                 row->UnsignedAttribute("width", /*Default*/0),
                 row->UnsignedAttribute("height", /*Default*/0)};
-            limit.fpsUpperBound = row->FloatAttribute("fpsBound", /*Default*/1000.0);
+            limit.fpsUpperBound = row->DoubleAttribute("fpsBound", /*Default*/1000.0);
             if (limit.size.width <= prevLimit.size.width ||
                     limit.size.height <= prevLimit.size.height ||
                     limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index a7eb121..9c0ad7f 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -91,6 +91,7 @@
             const std::vector<SupportedV4L2Format>& sortedFormats,
             const CroppingType& croppingType,
             const common::V1_0::helper::CameraMetadata& chars,
+            const std::string& cameraId,
             unique_fd v4l2Fd);
     virtual ~ExternalCameraDeviceSession();
     // Call by CameraDevice to dump active device states
@@ -180,7 +181,7 @@
     int v4l2StreamOffLocked();
 
     // TODO: change to unique_ptr for better tracking
-    sp<V4L2Frame> dequeueV4l2FrameLocked(); // Called with mLock hold
+    sp<V4L2Frame> dequeueV4l2FrameLocked(/*out*/nsecs_t* shutterTs); // Called with mLock hold
     void enqueueV4l2Frame(const sp<V4L2Frame>&);
 
     // Check if input Stream is one of supported stream setting on this device
@@ -198,8 +199,8 @@
 
     Status processOneCaptureRequest(const CaptureRequest& request);
 
-    Status processCaptureResult(HalRequest&);
-    Status processCaptureRequestError(HalRequest&);
+    Status processCaptureResult(std::shared_ptr<HalRequest>&);
+    Status processCaptureRequestError(const std::shared_ptr<HalRequest>&);
     void notifyShutter(uint32_t frameNumber, nsecs_t shutterTs);
     void notifyError(uint32_t frameNumber, int32_t streamId, ErrorCode ec);
     void invokeProcessCaptureResultCallback(
@@ -219,8 +220,9 @@
         Status allocateIntermediateBuffers(
                 const Size& v4lSize, const Size& thumbSize,
                 const hidl_vec<Stream>& streams);
-        Status submitRequest(const HalRequest&);
+        Status submitRequest(const std::shared_ptr<HalRequest>&);
         void flush();
+        void dump(int fd);
         virtual bool threadLoop() override;
 
     private:
@@ -232,9 +234,13 @@
         static int getCropRect(
                 CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out);
 
-        static const int kReqWaitTimeoutSec = 3;
+        static const int kFlushWaitTimeoutSec = 3; // 3 sec
+        static const int kReqWaitTimeoutMs = 33;   // 33ms
+        static const int kReqWaitTimesMax = 90;    // 33ms * 90 ~= 3 sec
 
-        void waitForNextRequest(HalRequest* out);
+        void waitForNextRequest(std::shared_ptr<HalRequest>* out);
+        void signalRequestDone();
+
         int cropAndScaleLocked(
                 sp<AllocatedFrame>& in, const Size& outSize,
                 YCbCrLayout* out);
@@ -252,17 +258,24 @@
                 void *out, size_t maxOutSize,
                 size_t &actualCodeSize);
 
-        int createJpegLocked(HalStreamBuffer &halBuf, HalRequest &req);
+        int createJpegLocked(HalStreamBuffer &halBuf, const std::shared_ptr<HalRequest>& req);
 
-        mutable std::mutex mLock;
-        std::condition_variable mRequestCond;
-        wp<ExternalCameraDeviceSession> mParent;
-        CroppingType mCroppingType;
-        std::list<HalRequest> mRequestList;
+        const wp<ExternalCameraDeviceSession> mParent;
+        const CroppingType mCroppingType;
+
+        mutable std::mutex mRequestListLock;      // Protect acccess to mRequestList,
+                                                  // mProcessingRequest and mProcessingFrameNumer
+        std::condition_variable mRequestCond;     // signaled when a new request is submitted
+        std::condition_variable mRequestDoneCond; // signaled when a request is done processing
+        std::list<std::shared_ptr<HalRequest>> mRequestList;
+        bool mProcessingRequest = false;
+        uint32_t mProcessingFrameNumer = 0;
+
         // V4L2 frameIn
         // (MJPG decode)-> mYu12Frame
         // (Scale)-> mScaledYu12Frames
         // (Format convert) -> output gralloc frames
+        mutable std::mutex mBufferLock; // Protect access to intermediate buffers
         sp<AllocatedFrame> mYu12Frame;
         sp<AllocatedFrame> mYu12ThumbFrame;
         std::unordered_map<Size, sp<AllocatedFrame>, SizeHasher> mIntermediateBuffers;
@@ -280,7 +293,9 @@
     const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
     const std::vector<SupportedV4L2Format> mSupportedFormats;
     const CroppingType mCroppingType;
+    const std::string& mCameraId;
     unique_fd mV4l2Fd;
+
     // device is closed either
     //    - closed by user
     //    - init failed
@@ -299,6 +314,7 @@
     std::condition_variable mV4L2BufferReturned;
     size_t mNumDequeuedV4l2Buffers = 0;
 
+    // Not protected by mLock (but might be used when mLock is locked)
     sp<OutputThread> mOutputThread;
 
     // Stream ID -> Camera3Stream cache
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
index e56160a..37e7cfb 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h
@@ -73,7 +73,7 @@
 
     struct FpsLimitation {
         Size size;
-        float fpsUpperBound;
+        double fpsUpperBound;
     };
     std::vector<FpsLimitation> fpsLimits;
 
@@ -93,7 +93,12 @@
     uint32_t height;
     uint32_t fourcc;
     // All supported frame rate for this w/h/fourcc combination
-    std::vector<float> frameRates;
+    struct FrameRate {
+        uint32_t durationNumerator;   // frame duration numerator.   Ex: 1
+        uint32_t durationDenominator; // frame duration denominator. Ex: 30
+        double getDouble() const;     // FrameRate in double.        Ex: 30.0
+    };
+    std::vector<FrameRate> frameRates;
 };
 
 // A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format)
diff --git a/camera/device/3.4/types.hal b/camera/device/3.4/types.hal
index 5681a5c..bf2b3fc 100644
--- a/camera/device/3.4/types.hal
+++ b/camera/device/3.4/types.hal
@@ -177,9 +177,14 @@
 
     /**
      * If fmqSettingsSize is zero, the settings buffer contains the capture and
-     * processing parameters for the physical device with id 'phyCamId'.
-     * In case the individual settings are empty or missing, Hal should fail the
-     * request and return Status::ILLEGAL_ARGUMENT.
+     * processing parameters for the physical device with id 'physicalCameraId'.
+     * As a special case, an empty settings buffer indicates that the
+     * settings are identical to the most-recently submitted capture request.
+     * An empty buffer cannot be used as the first submitted request after
+     * a configureStreams() call.
+     *
+     * This field must be used if fmqSettingsSize is zero. It must not be used
+     * if fmqSettingsSize is non-zero.
      */
     CameraMetadata settings;
 };
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 1405ea9..e78dbe8 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -116,6 +116,7 @@
 const int64_t kTorchTimeoutSec = 1;
 const int64_t kEmptyFlushTimeoutMSec = 200;
 const char kDumpOutput[] = "/dev/null";
+const uint32_t kBurstFrameCount = 10;
 
 struct AvailableStream {
     int32_t width;
@@ -655,6 +656,13 @@
     static Status isLogicalMultiCamera(camera_metadata_t *staticMeta);
     static Status getPhysicalCameraIds(camera_metadata_t *staticMeta,
             std::unordered_set<std::string> *physicalIds/*out*/);
+    static Status getSupportedKeys(camera_metadata_t *staticMeta,
+            uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
+    static void constructFilteredSettings(const sp<ICameraDeviceSession>& session,
+            const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
+            android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/,
+            android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings
+            /*out*/);
     static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
             AvailableStream &hfrStream);
     static Status isZSLModeAvailable(camera_metadata_t *staticMeta);
@@ -712,6 +720,20 @@
         // return from HAL but framework.
         ::android::Vector<StreamBuffer> resultOutputBuffers;
 
+        InFlightRequest() :
+                shutterTimestamp(0),
+                errorCodeValid(false),
+                errorCode(ErrorCode::ERROR_BUFFER),
+                usePartialResult(false),
+                numPartialResults(0),
+                resultQueue(nullptr),
+                haveResultMetadata(false),
+                numBuffersLeft(0),
+                frameNumber(0),
+                partialResultCount(0),
+                errorStreamId(-1),
+                hasInputBuffer(false) {}
+
         InFlightRequest(ssize_t numBuffers, bool hasInput,
                 bool partialResults, uint32_t partialCount,
                 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
@@ -2748,42 +2770,23 @@
         castSession(session, deviceVersion, &session3_3, &session3_4);
         ASSERT_NE(session3_4, nullptr);
 
-        const android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
-                staticMetaBuffer);
-        camera_metadata_ro_entry availableSessionKeys = staticMeta.find(
-                ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
-        if (availableSessionKeys.count == 0) {
+        std::unordered_set<int32_t> availableSessionKeys;
+        auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
+                &availableSessionKeys);
+        ASSERT_TRUE(Status::OK == rc);
+        if (availableSessionKeys.empty()) {
+            free_camera_metadata(staticMetaBuffer);
             ret = session->close();
             ASSERT_TRUE(ret.isOk());
             continue;
         }
 
         android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
-        ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
-                [&previewRequestSettings] (auto status, const auto& req) mutable {
-                    ASSERT_EQ(Status::OK, status);
-
-                    const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> (
-                            req.data());
-                    size_t expectedSize = req.size();
-                    int result = validate_camera_metadata_structure(metadata, &expectedSize);
-                    ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
-
-                    size_t entryCount = get_camera_metadata_entry_count(metadata);
-                    ASSERT_GT(entryCount, 0u);
-                    previewRequestSettings = metadata;
-                    });
-        ASSERT_TRUE(ret.isOk());
-        const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings =
-            previewRequestSettings;
         android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams;
-        for (size_t i = 0; i < availableSessionKeys.count; i++) {
-            camera_metadata_ro_entry entry = constSettings.find(availableSessionKeys.data.i32[i]);
-            if (entry.count > 0) {
-                sessionParams.update(entry);
-            }
-        }
+        constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW,
+                &previewRequestSettings, &sessionParams);
         if (sessionParams.isEmpty()) {
+            free_camera_metadata(staticMetaBuffer);
             ret = session->close();
             ASSERT_TRUE(ret.isOk());
             continue;
@@ -2817,7 +2820,7 @@
                 });
         ASSERT_TRUE(ret.isOk());
 
-        sessionParams.unlock(sessionParamsBuffer);
+        free_camera_metadata(staticMetaBuffer);
         ret = session->close();
         ASSERT_TRUE(ret.isOk());
     }
@@ -3350,6 +3353,8 @@
         if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
             continue;
         }
+        std::string version, deviceId;
+        ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId));
         camera_metadata_t* staticMeta;
         Return<void> ret;
         sp<ICameraDeviceSession> session;
@@ -3357,6 +3362,7 @@
 
         Status rc = isLogicalMultiCamera(staticMeta);
         if (Status::METHOD_NOT_SUPPORTED == rc) {
+            free_camera_metadata(staticMeta);
             ret = session->close();
             ASSERT_TRUE(ret.isOk());
             continue;
@@ -3366,13 +3372,45 @@
         ASSERT_TRUE(Status::OK == rc);
         ASSERT_TRUE(physicalIds.size() > 1);
 
+        std::unordered_set<int32_t> physicalRequestKeyIDs;
+        rc = getSupportedKeys(staticMeta,
+                ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
+        ASSERT_TRUE(Status::OK == rc);
+        if (physicalRequestKeyIDs.empty()) {
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            // The logical camera doesn't support any individual physical requests.
+            continue;
+        }
+
+        android::hardware::camera::common::V1_0::helper::CameraMetadata defaultPreviewSettings;
+        android::hardware::camera::common::V1_0::helper::CameraMetadata filteredSettings;
+        constructFilteredSettings(session, physicalRequestKeyIDs, RequestTemplate::PREVIEW,
+                &defaultPreviewSettings, &filteredSettings);
+        if (filteredSettings.isEmpty()) {
+            // No physical device settings in default request.
+            free_camera_metadata(staticMeta);
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
+        const camera_metadata_t *settingsBuffer = defaultPreviewSettings.getAndLock();
+        settings.setToExternal(
+                reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (settingsBuffer)),
+                get_camera_metadata_size(settingsBuffer));
+
         free_camera_metadata(staticMeta);
         ret = session->close();
         ASSERT_TRUE(ret.isOk());
 
-        // Leave only 2 physical devices in the id set.
-        auto it = physicalIds.begin(); it++; it++;
-        physicalIds.erase(it, physicalIds.end());
+        auto it = physicalIds.begin();
+        string physicalDeviceId = *it;
+        // Leave only the first physical device in the id set and insert the logical device.
+        physicalIds.erase(++it, physicalIds.end());
+        physicalIds.emplace(deviceId);
+        ASSERT_EQ(physicalIds.size(), 2u);
 
         V3_4::HalStreamConfiguration halStreamConfig;
         bool supportsPartialResults = false;
@@ -3400,38 +3438,34 @@
                 });
         ASSERT_TRUE(resultQueueRet.isOk());
 
-        InFlightRequest inflightReq = {static_cast<ssize_t> (physicalIds.size()), false,
+        InFlightRequest inflightReq = {static_cast<ssize_t> (halStreamConfig.streams.size()), false,
             supportsPartialResults, partialResultCount, resultQueue};
 
-        RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-        ret = session3_4->constructDefaultRequestSettings(reqTemplate,
-                                                       [&](auto status, const auto& req) {
-                                                           ASSERT_EQ(Status::OK, status);
-                                                           settings = req;
-                                                       });
-        ASSERT_TRUE(ret.isOk());
-        ASSERT_TRUE(settings.size() > 0);
-
         std::vector<sp<GraphicBuffer>> graphicBuffers;
-        graphicBuffers.reserve(physicalIds.size());
+        graphicBuffers.reserve(halStreamConfig.streams.size());
         ::android::hardware::hidl_vec<StreamBuffer> outputBuffers;
-        outputBuffers.resize(physicalIds.size());
-        hidl_vec<V3_4::PhysicalCameraSetting> camSettings;
-        camSettings.resize(physicalIds.size());
+        outputBuffers.resize(halStreamConfig.streams.size());
         size_t k = 0;
-        for (const auto physicalIdIt : physicalIds) {
+        for (const auto& halStream : halStreamConfig.streams) {
             sp<GraphicBuffer> gb = new GraphicBuffer(previewStream.width, previewStream.height,
-                    static_cast<int32_t>(halStreamConfig.streams[k].v3_3.v3_2.overrideFormat), 1,
+                    static_cast<int32_t>(halStream.v3_3.v3_2.overrideFormat), 1,
                     android_convertGralloc1To0Usage(
-                        halStreamConfig.streams[k].v3_3.v3_2.producerUsage,
-                        halStreamConfig.streams[k].v3_3.v3_2.consumerUsage));
+                        halStream.v3_3.v3_2.producerUsage, halStream.v3_3.v3_2.consumerUsage));
             ASSERT_NE(nullptr, gb.get());
-            outputBuffers[k] = {halStreamConfig.streams[k].v3_3.v3_2.id, bufferId,
-                hidl_handle(gb->getNativeBuffer()->handle), BufferStatus::OK, nullptr, nullptr};
             graphicBuffers.push_back(gb);
-            camSettings[k] = {0, hidl_string(physicalIdIt), settings};
+            outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId,
+                hidl_handle(gb->getNativeBuffer()->handle), BufferStatus::OK, nullptr, nullptr};
+            bufferId++;
             k++;
         }
+        hidl_vec<V3_4::PhysicalCameraSetting> camSettings(1);
+        const camera_metadata_t *filteredSettingsBuffer = filteredSettings.getAndLock();
+        camSettings[0].settings.setToExternal(
+                reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (
+                        filteredSettingsBuffer)),
+                get_camera_metadata_size(filteredSettingsBuffer));
+        camSettings[0].fmqSettingsSize = 0;
+        camSettings[0].physicalCameraId = physicalDeviceId;
 
         StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
         V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
@@ -3468,24 +3502,49 @@
 
             ASSERT_FALSE(inflightReq.errorCodeValid);
             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+
+            request.v3_2.frameNumber++;
+            // Empty settings should be supported after the first call
+            // for repeating requests.
+            request.v3_2.settings.setToExternal(nullptr, 0, true);
+            request.physicalCameraSettings[0].settings.setToExternal(nullptr, 0, true);
+            // The buffer has been registered to HAL by bufferId, so per
+            // API contract we should send a null handle for this buffer
+            request.v3_2.outputBuffers[0].buffer = nullptr;
+            mInflightMap.clear();
+            inflightReq = {static_cast<ssize_t> (physicalIds.size()), false,
+                supportsPartialResults, partialResultCount, resultQueue};
+            mInflightMap.add(request.v3_2.frameNumber, &inflightReq);
         }
 
-        // Empty physical camera settings should fail process requests
-        camSettings[1].settings = emptySettings;
-        frameNumber++;
-        request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
-            emptyInputBuffer, outputBuffers}, camSettings};
         returnStatus = session3_4->processCaptureRequest_3_4(
             {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
                 stat = s;
                 numRequestProcessed = n;
             });
         ASSERT_TRUE(returnStatus.isOk());
-        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat);
+        ASSERT_EQ(Status::OK, stat);
+        ASSERT_EQ(numRequestProcessed, 1u);
+
+        {
+            std::unique_lock<std::mutex> l(mLock);
+            while (!inflightReq.errorCodeValid &&
+                    ((0 < inflightReq.numBuffersLeft) ||
+                     (!inflightReq.haveResultMetadata))) {
+                auto timeout = std::chrono::system_clock::now() +
+                    std::chrono::seconds(kStreamBufferTimeoutSec);
+                ASSERT_NE(std::cv_status::timeout,
+                        mResultCondition.wait_until(l, timeout));
+            }
+
+            ASSERT_FALSE(inflightReq.errorCodeValid);
+            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+        }
 
         // Invalid physical camera id should fail process requests
-        camSettings[1].physicalCameraId = invalidPhysicalId;
-        camSettings[1].settings = settings;
+        frameNumber++;
+        camSettings[0].physicalCameraId = invalidPhysicalId;
+        camSettings[0].settings = settings;
         request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
             emptyInputBuffer, outputBuffers}, camSettings};
         returnStatus = session3_4->processCaptureRequest_3_4(
@@ -3496,11 +3555,158 @@
         ASSERT_TRUE(returnStatus.isOk());
         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat);
 
+        defaultPreviewSettings.unlock(settingsBuffer);
+        filteredSettings.unlock(filteredSettingsBuffer);
         ret = session3_4->close();
         ASSERT_TRUE(ret.isOk());
     }
 }
 
+// Generate and verify a burst containing alternating sensor sensitivity values
+TEST_F(CameraHidlTest, processCaptureRequestBurstISO) {
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                        static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    uint64_t bufferId = 1;
+    uint32_t frameNumber = 1;
+    ::android::hardware::hidl_vec<uint8_t> settings;
+
+    for (const auto& name : cameraDeviceNames) {
+        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
+            continue;
+        } else if (deviceVersion <= 0) {
+            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+            ADD_FAILURE();
+            return;
+        }
+        camera_metadata_t* staticMetaBuffer;
+        Return<void> ret;
+        sp<ICameraDeviceSession> session;
+        openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
+                staticMetaBuffer);
+
+        camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
+        ASSERT_TRUE(0 < hwLevel.count);
+        if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0]) {
+            //Limited devices can skip this test
+            ret = session->close();
+            ASSERT_TRUE(ret.isOk());
+            continue;
+        }
+
+        camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
+        ASSERT_EQ(isoRange.count, 2u);
+
+        ret = session->close();
+        ASSERT_TRUE(ret.isOk());
+
+        bool supportsPartialResults = false;
+        uint32_t partialResultCount = 0;
+        V3_2::Stream previewStream;
+        HalStreamConfiguration halStreamConfig;
+        configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold,
+                &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/,
+                &supportsPartialResults /*out*/, &partialResultCount /*out*/);
+        std::shared_ptr<ResultMetadataQueue> resultQueue;
+
+        auto resultQueueRet = session->getCaptureResultMetadataQueue(
+            [&resultQueue](const auto& descriptor) {
+                resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
+                if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+                    ALOGE("%s: HAL returns empty result metadata fmq,"
+                            " not use it", __func__);
+                    resultQueue = nullptr;
+                    // Don't use the queue onwards.
+                }
+            });
+        ASSERT_TRUE(resultQueueRet.isOk());
+        ASSERT_NE(nullptr, resultQueue);
+
+        ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
+            [&](auto status, const auto& req) {
+                ASSERT_EQ(Status::OK, status);
+                settings = req; });
+        ASSERT_TRUE(ret.isOk());
+
+        ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
+        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
+        sp<GraphicBuffer> buffers[kBurstFrameCount];
+        StreamBuffer outputBuffers[kBurstFrameCount];
+        CaptureRequest requests[kBurstFrameCount];
+        InFlightRequest inflightReqs[kBurstFrameCount];
+        int32_t isoValues[kBurstFrameCount];
+        hidl_vec<uint8_t> requestSettings[kBurstFrameCount];
+        for (uint32_t i = 0; i < kBurstFrameCount; i++) {
+            std::unique_lock<std::mutex> l(mLock);
+
+            isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1];
+            buffers[i] = new GraphicBuffer( previewStream.width, previewStream.height,
+                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1,
+                android_convertGralloc1To0Usage( halStreamConfig.streams[0].producerUsage,
+                    halStreamConfig.streams[0].consumerUsage));
+            ASSERT_NE(nullptr, buffers[i].get());
+
+            outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i,
+                hidl_handle( buffers[i]->getNativeBuffer()->handle), BufferStatus::OK, nullptr,
+                nullptr};
+            requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data()));
+
+            // Disable all 3A routines
+            uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
+            ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1));
+            ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i],
+                        1));
+            camera_metadata_t *metaBuffer = requestMeta.release();
+            requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer),
+                    get_camera_metadata_size(metaBuffer), true);
+
+            requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i],
+                emptyInputBuffer, {outputBuffers[i]}};
+
+            inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount, resultQueue};
+            mInflightMap.add(frameNumber + i, &inflightReqs[i]);
+        }
+
+        Status status = Status::INTERNAL_ERROR;
+        uint32_t numRequestProcessed = 0;
+        hidl_vec<BufferCache> cachesToRemove;
+        hidl_vec<CaptureRequest> burstRequest;
+        burstRequest.setToExternal(requests, kBurstFrameCount);
+        Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove,
+                [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                    status = s;
+                    numRequestProcessed = n;
+                });
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, status);
+        ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
+
+        for (size_t i = 0; i < kBurstFrameCount; i++) {
+            std::unique_lock<std::mutex> l(mLock);
+            while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) ||
+                            (!inflightReqs[i].haveResultMetadata))) {
+                auto timeout = std::chrono::system_clock::now() +
+                        std::chrono::seconds(kStreamBufferTimeoutSec);
+                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+            }
+
+            ASSERT_FALSE(inflightReqs[i].errorCodeValid);
+            ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
+            ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
+            ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
+            ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
+            camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
+                    ANDROID_SENSOR_SENSITIVITY);
+            ASSERT_TRUE(isoResult.data.i32[0] == isoValues[i]);
+        }
+
+        ret = session->close();
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
 // Test whether an incorrect capture request with missing settings will
 // be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
@@ -3901,6 +4107,56 @@
     return Status::OK;
 }
 
+// Generate a set of suported camera key ids.
+Status CameraHidlTest::getSupportedKeys(camera_metadata_t *staticMeta,
+        uint32_t tagId, std::unordered_set<int32_t> *requestIDs) {
+    if ((nullptr == staticMeta) || (nullptr == requestIDs)) {
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    camera_metadata_ro_entry entry;
+    int rc = find_camera_metadata_ro_entry(staticMeta, tagId, &entry);
+    if ((0 != rc) || (entry.count == 0)) {
+        return Status::OK;
+    }
+
+    requestIDs->insert(entry.data.i32, entry.data.i32 + entry.count);
+
+    return Status::OK;
+}
+
+void CameraHidlTest::constructFilteredSettings(const sp<ICameraDeviceSession>& session,
+        const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
+        android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings,
+        android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings) {
+    ASSERT_NE(defaultSettings, nullptr);
+    ASSERT_NE(filteredSettings, nullptr);
+
+    auto ret = session->constructDefaultRequestSettings(reqTemplate,
+            [&defaultSettings] (auto status, const auto& req) mutable {
+                ASSERT_EQ(Status::OK, status);
+
+                const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> (
+                        req.data());
+                size_t expectedSize = req.size();
+                int result = validate_camera_metadata_structure(metadata, &expectedSize);
+                ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+
+                size_t entryCount = get_camera_metadata_entry_count(metadata);
+                ASSERT_GT(entryCount, 0u);
+                *defaultSettings = metadata;
+                });
+    ASSERT_TRUE(ret.isOk());
+    const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings =
+        *defaultSettings;
+    for (const auto& keyIt : availableKeys) {
+        camera_metadata_ro_entry entry = constSettings.find(keyIt);
+        if (entry.count > 0) {
+            filteredSettings->update(entry);
+        }
+    }
+}
+
 // Check if constrained mode is supported by using the static
 // camera characteristics.
 Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp
index e1e09e9..0db9bb0 100644
--- a/cas/1.0/vts/functional/Android.bp
+++ b/cas/1.0/vts/functional/Android.bp
@@ -23,6 +23,7 @@
         "android.hardware.cas.native@1.0",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libhidlallocatorutils",
         "libhidlmemory",
     ],
     shared_libs: [
diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
index 053d37a..14b8bbd 100644
--- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
+++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
@@ -30,6 +30,7 @@
 #include <hidl/HidlSupport.h>
 #include <hidl/HidlTransportSupport.h>
 #include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
 
@@ -53,6 +54,7 @@
 using android::hardware::cas::V1_0::ICas;
 using android::hardware::cas::V1_0::ICasListener;
 using android::hardware::cas::V1_0::IDescramblerBase;
+using android::hardware::cas::V1_0::Status;
 using android::hardware::cas::native::V1_0::IDescrambler;
 using android::hardware::cas::native::V1_0::SubSample;
 using android::hardware::cas::native::V1_0::SharedBuffer;
@@ -61,13 +63,12 @@
 using android::hardware::cas::native::V1_0::ScramblingControl;
 using android::hardware::cas::V1_0::IMediaCasService;
 using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
-using android::hardware::Void;
+using android::hardware::fromHeap;
 using android::hardware::hidl_vec;
 using android::hardware::hidl_string;
-using android::hardware::hidl_handle;
-using android::hardware::hidl_memory;
+using android::hardware::HidlMemory;
 using android::hardware::Return;
-using android::hardware::cas::V1_0::Status;
+using android::hardware::Void;
 using android::IMemory;
 using android::IMemoryHeap;
 using android::MemoryDealer;
@@ -315,7 +316,7 @@
     }
     *inMemory = mem;
 
-    // build hidl_memory from memory heap
+    // build HidlMemory from memory heap
     ssize_t offset;
     size_t size;
     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -324,18 +325,14 @@
         return ::testing::AssertionFailure();
     }
 
-    native_handle_t* nativeHandle = native_handle_create(1, 0);
-    if (!nativeHandle) {
-        ALOGE("failed to create native handle!");
-        return ::testing::AssertionFailure();
-    }
-    nativeHandle->data[0] = heap->getHeapID();
-
     uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
     memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
 
+    // hidlMemory is not to be passed out of scope!
+    sp<HidlMemory> hidlMemory = fromHeap(heap);
+
     SharedBuffer srcBuffer = {
-            .heapBase = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize()),
+            .heapBase = *hidlMemory,
             .offset = (uint64_t) offset,
             .size = (uint64_t) size
     };
@@ -380,7 +377,7 @@
         return ::testing::AssertionFailure();
     }
 
-    // build hidl_memory from memory heap
+    // build HidlMemory from memory heap
     ssize_t offset;
     size_t size;
     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -389,15 +386,11 @@
         return ::testing::AssertionFailure();
     }
 
-    native_handle_t* nativeHandle = native_handle_create(1, 0);
-    if (!nativeHandle) {
-        ALOGE("failed to create native handle!");
-        return ::testing::AssertionFailure();
-    }
-    nativeHandle->data[0] = heap->getHeapID();
+    // hidlMemory is not to be passed out of scope!
+    sp<HidlMemory> hidlMemory = fromHeap(heap);
 
     SharedBuffer srcBuffer = {
-            .heapBase = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize()),
+            .heapBase = *hidlMemory,
             .offset = (uint64_t) offset + params.imemOffset,
             .size = (uint64_t) params.imemSize,
     };
diff --git a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp
index 5672824..7492152 100644
--- a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp
+++ b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "contexthub_hidl_hal_test"
 
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/contexthub/1.0/IContexthub.h>
 #include <android/hardware/contexthub/1.0/IContexthubCallback.h>
@@ -92,12 +93,27 @@
   return hubIds;
 }
 
+// Test environment for Contexthub HIDL HAL.
+class ContexthubHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+  // get the test environment singleton
+  static ContexthubHidlEnvironment* Instance() {
+    static ContexthubHidlEnvironment* instance = new ContexthubHidlEnvironment;
+    return instance;
+  }
+
+  virtual void registerTestServices() override { registerTestService<IContexthub>(); }
+ private:
+  ContexthubHidlEnvironment() {}
+};
+
 // Base test fixture that initializes the HAL and makes the context hub API
 // handle available
 class ContexthubHidlTestBase : public ::testing::VtsHalHidlTargetTestBase {
  public:
   virtual void SetUp() override {
-    hubApi = ::testing::VtsHalHidlTargetTestBase::getService<IContexthub>();
+    hubApi = ::testing::VtsHalHidlTargetTestBase::getService<IContexthub>(
+        ContexthubHidlEnvironment::Instance()->getServiceName<IContexthub>());
     ASSERT_NE(hubApi, nullptr);
 
     // getHubs() must be called at least once for proper initialization of the
@@ -381,7 +397,11 @@
 } // anonymous namespace
 
 int main(int argc, char **argv) {
+  ::testing::AddGlobalTestEnvironment(ContexthubHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
+  ContexthubHidlEnvironment::Instance()->init(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  ALOGI ("Test result = %d", status);
+  return status;
 }
 
diff --git a/current.txt b/current.txt
index a5ab307..de2511e 100644
--- a/current.txt
+++ b/current.txt
@@ -255,4 +255,5 @@
 fb92e2b40f8e9d494e8fd3b4ac18499a3216342e7cff160714c3bbf3660b6e79 android.hardware.gnss@1.0::IGnssConfiguration
 251594ea9b27447bfa005ebd806e58fb0ae4aad84a69938129c9800ec0c64eda android.hardware.gnss@1.0::IGnssMeasurementCallback
 4e7169919d24fbe5573e5bcd683d0bd7abf553a4e6c34c41f9dfc1e12050db07 android.hardware.gnss@1.0::IGnssNavigationMessageCallback
+0e6e80ddd5c312726e20b003af438325a2d7c305a60a8c8d8e229df2306d50df android.hardware.radio@1.0::types
 b280c4704dfcc548a9bf127b59b7c3578f460c50cce70a06b66fe0df8b27cff0 android.hardware.wifi@1.0::types
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 47c6950..d03b2af 100644
--- a/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
+++ b/drm/1.0/vts/functional/drm_hal_vendor_test.cpp
@@ -97,6 +97,27 @@
 
 static drm_vts::VendorModules* gVendorModules = nullptr;
 
+// Test environment for drm
+class DrmHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static DrmHidlEnvironment* Instance() {
+        static DrmHidlEnvironment* instance = new DrmHidlEnvironment;
+        return instance;
+    }
+
+    void registerTestServices() override {
+        registerTestService<ICryptoFactory>();
+        registerTestService<IDrmFactory>();
+        setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
+    }
+
+   private:
+    DrmHidlEnvironment() {}
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(DrmHidlEnvironment);
+};
+
 class DrmHalVendorFactoryTest : public testing::TestWithParam<std::string> {
    public:
     DrmHalVendorFactoryTest()
@@ -1598,6 +1619,10 @@
         std::cerr << "WARNING: No vendor modules found in " << kModulePath <<
                 ", all vendor tests will be skipped" << std::endl;
     }
+    ::testing::AddGlobalTestEnvironment(DrmHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
+    DrmHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    ALOGI("Test result = %d", status);
+    return status;
 }
diff --git a/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp b/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp
index a8ed0e5..061f2cd 100644
--- a/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp
+++ b/drm/1.1/vts/functional/drm_hal_clearkey_test.cpp
@@ -106,6 +106,12 @@
 
     virtual void HidlTearDown() override { ALOGI("TearDown DrmHidlEnvironment"); }
 
+    void registerTestServices() override {
+        registerTestService<ICryptoFactory>();
+        registerTestService<IDrmFactory>();
+        setServiceCombMode(::testing::HalServiceCombMode::NO_COMBINATION);
+    }
+
    private:
     DrmHidlEnvironment() {}
 
diff --git a/gnss/1.1/Android.bp b/gnss/1.1/Android.bp
index 417b4f5..4ae4439 100644
--- a/gnss/1.1/Android.bp
+++ b/gnss/1.1/Android.bp
@@ -11,6 +11,7 @@
         "IGnssCallback.hal",
         "IGnssConfiguration.hal",
         "IGnssMeasurement.hal",
+        "IGnssMeasurementCallback.hal",
     ],
     interfaces: [
         "android.hardware.gnss@1.0",
diff --git a/gnss/1.1/IGnssMeasurement.hal b/gnss/1.1/IGnssMeasurement.hal
index 75df5a8..cd83ae3 100644
--- a/gnss/1.1/IGnssMeasurement.hal
+++ b/gnss/1.1/IGnssMeasurement.hal
@@ -17,7 +17,7 @@
 package android.hardware.gnss@1.1;
 
 import @1.0::IGnssMeasurement;
-import @1.0::IGnssMeasurementCallback;
+import IGnssMeasurementCallback;
 
 /**
  * Extended interface for GNSS Measurements support.
diff --git a/gnss/1.1/IGnssMeasurementCallback.hal b/gnss/1.1/IGnssMeasurementCallback.hal
new file mode 100644
index 0000000..5a60a56
--- /dev/null
+++ b/gnss/1.1/IGnssMeasurementCallback.hal
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss@1.1;
+
+import @1.0::IGnssMeasurementCallback;
+
+/** The callback interface to report measurements from the HAL. */
+interface IGnssMeasurementCallback extends @1.0::IGnssMeasurementCallback {
+    /**
+     * Flags indicating the Accumulated Delta Range's states.
+     */
+    enum GnssAccumulatedDeltaRangeState
+            : @1.0::IGnssMeasurementCallback.GnssAccumulatedDeltaRangeState {
+        ADR_STATE_HALF_CYCLE_RESOLVED = 1 << 3, // Carrier-phase half-cycle ambiguity resolved
+    };
+
+    /**
+     * Extends a GNSS Measurement, adding the new enum.
+     */
+    struct GnssMeasurement {
+        /**
+         * GNSS measurement information for a single satellite and frequency, as in the 1.0
+         * version of the HAL.
+         *
+         * In this version of the HAL, these fields of the
+         * @1.0::IGnssMeasurementCallback.GnssMeasurement v1_0 struct are deprecated, and
+         * are no longer used by the framework:
+         *   carrierCycles
+         *   carrierPhase
+         *   carrierPhaseUncertainty
+         *
+         * Similar information about carrier phase signal tracking is still reported in these
+         * fields of @1.0::IGnssMeasurementCallback.GnssMeasurement v1_0:
+         *   accumulatedDeltaRangeM
+         *   accumulatedDeltaRangeUncertaintyM
+         */
+        @1.0::IGnssMeasurementCallback.GnssMeasurement v1_0;
+
+        /**
+         * Provides the state of Accumulated Delta Range values, including additional information
+         * beyond version 1.0 of the HAL.  See GnssAccumulatedDeltaRangeState.
+         *
+         * In this (1.1) version of the HAL, this value is used by the framework, not the
+         * value provided by v1_0.accumulatedDeltaRangeState.
+         */
+        bitfield<GnssAccumulatedDeltaRangeState> accumulatedDeltaRangeState;
+    };
+
+    /**
+     * Complete set of GNSS Measurement data, same as 1.0 with additional enum in measurements.
+     */
+    struct GnssData {
+        /** The full set of satellite measurement observations. */
+        vec<GnssMeasurement> measurements;
+
+        /** The GNSS clock time reading. */
+        GnssClock clock;
+    };
+
+    /**
+     * Callback for the hal to pass a GnssData structure back to the client.
+     *
+     * @param data Contains a reading of GNSS measurements.
+     */
+    gnssMeasurementCb(GnssData data);
+};
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index 264a11d..a0a1c73 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -396,6 +396,10 @@
 
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
+
+    auto resultVoid = gnss_hal_->deleteAidingData(IGnss::GnssAidingData::DELETE_ALL);
+
+    ASSERT_TRUE(resultVoid.isOk());
 }
 
 /*
diff --git a/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp b/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
index 324eb9f..335d15d 100644
--- a/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
+++ b/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
@@ -19,7 +19,9 @@
 #include <android/hardware/health/1.0/IHealth.h>
 #include <android/hardware/health/1.0/types.h>
 #include <log/log.h>
+
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 using HealthConfig = ::android::hardware::health::V1_0::HealthConfig;
 using HealthInfo = ::android::hardware::health::V1_0::HealthInfo;
@@ -28,10 +30,25 @@
 
 using ::android::sp;
 
+// Test environment for Health HIDL HAL.
+class HealthHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static HealthHidlEnvironment* Instance() {
+        static HealthHidlEnvironment* instance = new HealthHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IHealth>(); }
+   private:
+    HealthHidlEnvironment() {}
+};
+
 class HealthHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    public:
     virtual void SetUp() override {
-        health = ::testing::VtsHalHidlTargetTestBase::getService<IHealth>();
+        health = ::testing::VtsHalHidlTargetTestBase::getService<IHealth>(
+            HealthHidlEnvironment::Instance()->getServiceName<IHealth>());
         ASSERT_NE(health, nullptr);
         health->init(config,
                      [&](const auto& halConfigOut) { config = halConfigOut; });
@@ -57,7 +74,9 @@
 }
 
 int main(int argc, char **argv) {
+    ::testing::AddGlobalTestEnvironment(HealthHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
+    HealthHidlEnvironment::Instance()->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     ALOGI("Test result = %d", status);
     return status;
diff --git a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
index 3a181a9..fbe5237 100644
--- a/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/3.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2918,6 +2918,28 @@
 }
 
 /*
+ * EncryptionOperationsTest.AesEcbWithUserId
+ *
+ * Verifies that AES ECB mode works when Tag::USER_ID is specified.
+ */
+TEST_F(EncryptionOperationsTest, AesEcbWithUserId) {
+    string key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
+                                           .Authorization(TAG_NO_AUTH_REQUIRED)
+                                           .Authorization(TAG_USER_ID, 0)
+                                           .AesEncryptionKey(key.size() * 8)
+                                           .EcbMode()
+                                           .Padding(PaddingMode::PKCS7),
+                                       KeyFormat::RAW, key));
+
+    string message = "Hello World!";
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+    string ciphertext = EncryptMessage(message, params);
+    string plaintext = DecryptMessage(ciphertext, params);
+    EXPECT_EQ(message, plaintext);
+}
+
+/*
  * EncryptionOperationsTest.AesEcbRoundTripSuccess
  *
  * Verifies that AES encryption fails in the correct way when an unauthorized mode is specified.
diff --git a/keymaster/4.0/support/Keymaster3.cpp b/keymaster/4.0/support/Keymaster3.cpp
index b2cdbd9..84b3ee1 100644
--- a/keymaster/4.0/support/Keymaster3.cpp
+++ b/keymaster/4.0/support/Keymaster3.cpp
@@ -61,9 +61,12 @@
 }
 
 hidl_vec<V3_0::KeyParameter> convert(const hidl_vec<KeyParameter>& params) {
-    hidl_vec<V3_0::KeyParameter> converted(params.size());
-    for (size_t i = 0; i < params.size(); ++i) {
-        converted[i] = convert(params[i]);
+    std::vector<V3_0::KeyParameter> converted;
+    converted.reserve(params.size());
+    for (const auto& param : params) {
+        // Qualcomm's Keymaster3 implementation behaves oddly if Tag::USER_ID is provided. Filter it
+        // out.  Revert this change when b/73286437 is fixed.
+        if (param.tag != Tag::USER_ID) converted.push_back(convert(param));
     }
     return converted;
 }
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
index 9d6501b..ce213bc 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
@@ -142,24 +142,28 @@
 DECLARE_TYPED_TAG(RSA_PUBLIC_EXPONENT);
 DECLARE_TYPED_TAG(TRUSTED_CONFIRMATION_REQUIRED);
 DECLARE_TYPED_TAG(UNIQUE_ID);
+DECLARE_TYPED_TAG(UNLOCKED_DEVICE_REQUIRED);
 DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME);
 DECLARE_TYPED_TAG(USER_AUTH_TYPE);
+DECLARE_TYPED_TAG(USER_ID);
 DECLARE_TYPED_TAG(USER_SECURE_ID);
 
 template <typename... Elems>
 struct MetaList {};
 
-using all_tags_t = MetaList<
-    TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t,
-    TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t,
-    TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t, TAG_MIN_SECONDS_BETWEEN_OPS_t,
-    TAG_MAX_USES_PER_BOOT_t, TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t,
-    TAG_ALLOW_WHILE_ON_BODY_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t,
-    TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t,
-    TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t,
-    TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_RESET_SINCE_ID_ROTATION_t,
-    TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t,
-    TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t>;
+using all_tags_t =
+    MetaList<TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t,
+             TAG_MIN_MAC_LENGTH_t, TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t,
+             TAG_ACTIVE_DATETIME_t, TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t,
+             TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USER_ID_t,
+             TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t,
+             TAG_ALLOW_WHILE_ON_BODY_t, TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t,
+             TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t,
+             TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t,
+             TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, TAG_ATTESTATION_CHALLENGE_t,
+             TAG_ATTESTATION_APPLICATION_ID_t, TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t,
+             TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t,
+             TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t>;
 
 template <typename TypedTagType>
 struct TypedTag2ValueType;
@@ -343,6 +347,7 @@
         case Tag::BOOTLOADER_ONLY:
         case Tag::NO_AUTH_REQUIRED:
         case Tag::ALLOW_WHILE_ON_BODY:
+        case Tag::UNLOCKED_DEVICE_REQUIRED:
         case Tag::ROLLBACK_RESISTANCE:
         case Tag::RESET_SINCE_ID_ROTATION:
         case Tag::TRUSTED_CONFIRMATION_REQUIRED:
@@ -357,6 +362,7 @@
         case Tag::OS_VERSION:
         case Tag::OS_PATCHLEVEL:
         case Tag::MAC_LENGTH:
+        case Tag::USER_ID:
         case Tag::AUTH_TIMEOUT:
         case Tag::VENDOR_PATCHLEVEL:
         case Tag::BOOT_PATCHLEVEL:
diff --git a/keymaster/4.0/types.hal b/keymaster/4.0/types.hal
index 91ec9bf..47fd1ed 100644
--- a/keymaster/4.0/types.hal
+++ b/keymaster/4.0/types.hal
@@ -118,7 +118,8 @@
                                                        * boot. */
 
     /* User authentication */
-    // 500-501 reserved
+    // 500 reserved
+    USER_ID = TagType:UINT | 501,             /* Android ID of authorized user or authenticator(s), */
     USER_SECURE_ID = TagType:ULONG_REP | 502, /* Secure ID of authorized user or authenticator(s).
                                                * Disallowed if NO_AUTH_REQUIRED is present. */
     NO_AUTH_REQUIRED = TagType:BOOL | 503,    /* If key is usable without authentication. */
@@ -191,6 +192,9 @@
      * match the data described in the token, keymaster must return NO_USER_CONFIRMATION. */
     TRUSTED_CONFIRMATION_REQUIRED = TagType:BOOL | 508,
 
+    UNLOCKED_DEVICE_REQUIRED = TagType:BOOL | 509, /* Require the device screen to be unlocked if
+                                                    * the key is used. */
+
     /* Application access control */
     APPLICATION_ID = TagType:BYTES | 601, /* Byte string identifying the authorized application. */
 
@@ -471,6 +475,7 @@
     PROOF_OF_PRESENCE_REQUIRED = -69,
     CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = -70,
     NO_USER_CONFIRMATION = -71,
+    DEVICE_LOCKED = -72,
 
     UNIMPLEMENTED = -100,
     VERSION_MISMATCH = -101,
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index e33ee77..54dd14a 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -14,22 +14,49 @@
 // limitations under the License.
 //
 
+cc_library_static {
+    name: "VtsHalNeuralnetworksTest_utils",
+    srcs: [
+        "Callbacks.cpp",
+        "Models.cpp",
+        "GeneratedTestHarness.cpp",
+    ],
+    defaults: ["VtsHalTargetTestDefaults"],
+    export_include_dirs: ["."],
+    static_libs: [
+        "android.hardware.neuralnetworks@1.0",
+        "android.hardware.neuralnetworks@1.1",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libhidlmemory",
+        "libneuralnetworks_utils",
+    ],
+    header_libs: [
+        "libneuralnetworks_headers",
+        "libneuralnetworks_generated_test_harness_headers",
+        "libneuralnetworks_generated_tests",
+    ],
+}
+
 cc_test {
     name: "VtsHalNeuralnetworksV1_0TargetTest",
     srcs: [
-        "Callbacks.cpp",
-        "GeneratedTestHarness.cpp",
-        "Models.cpp",
-        "VtsHalNeuralnetworksV1_0TargetTest.cpp",
+        "VtsHalNeuralnetworksV1_0.cpp",
+        "VtsHalNeuralnetworksV1_0BasicTest.cpp",
+        "VtsHalNeuralnetworksV1_0GeneratedTest.cpp",
     ],
     defaults: ["VtsHalTargetTestDefaults"],
     static_libs: [
         "android.hardware.neuralnetworks@1.0",
+        "android.hardware.neuralnetworks@1.1",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
         "libhidlmemory",
+        "libneuralnetworks_utils",
+        "VtsHalNeuralnetworksTest_utils",
     ],
     header_libs: [
+        "libneuralnetworks_headers",
         "libneuralnetworks_generated_test_harness_headers",
         "libneuralnetworks_generated_tests",
     ],
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index d740b5f..5fe8415 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -16,9 +16,15 @@
 
 #include "Callbacks.h"
 #include "TestHarness.h"
-#include "VtsHalNeuralnetworksV1_0TargetTest.h"
+#include "Utils.h"
 
 #include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.0/IDevice.h>
+#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
+#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <hidlmemory/mapping.h>
 #include <iostream>
@@ -26,11 +32,6 @@
 namespace android {
 namespace hardware {
 namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
-// allocator helper
-hidl_memory allocateSharedMemory(int64_t size, const std::string& type = "ashmem");
 
 namespace generated_tests {
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
@@ -64,54 +65,10 @@
 
 // Top level driver for models and examples generated by test_generator.py
 // Test driver for those generated from ml/nn/runtime/test/spec
-void Execute(const sp<IDevice>& device, std::function<Model(void)> create_model,
-             std::function<bool(int)> is_ignored,
-             const std::vector<MixedTypedExampleType>& examples) {
+void EvaluatePreparedModel(sp<IPreparedModel>& preparedModel, std::function<bool(int)> is_ignored,
+                           const std::vector<MixedTypedExampleType>& examples) {
     const uint32_t INPUT = 0;
     const uint32_t OUTPUT = 1;
-    Model model = create_model();
-
-    // see if service can handle model
-    ErrorStatus supportedStatus;
-    bool fullySupportsModel = false;
-    Return<void> supportedCall = device->getSupportedOperations(
-        model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
-            supportedStatus = status;
-            ASSERT_NE(0ul, supported.size());
-            fullySupportsModel =
-                std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
-        });
-    ASSERT_TRUE(supportedCall.isOk());
-    ASSERT_EQ(ErrorStatus::NONE, supportedStatus);
-
-    // launch prepare model
-    sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
-    ASSERT_NE(nullptr, preparedModelCallback.get());
-    Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
-    ASSERT_TRUE(prepareLaunchStatus.isOk());
-
-    // retrieve prepared model
-    preparedModelCallback->wait();
-    ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
-    sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
-    if (fullySupportsModel) {
-        EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
-    } else {
-        EXPECT_TRUE(prepareReturnStatus == ErrorStatus::NONE ||
-                    prepareReturnStatus == ErrorStatus::GENERAL_FAILURE);
-    }
-
-    // early termination if vendor service cannot fully prepare model
-    if (!fullySupportsModel && prepareReturnStatus == ErrorStatus::GENERAL_FAILURE) {
-        ASSERT_EQ(nullptr, preparedModel.get());
-        LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
-                     "prepare model that it does not support.";
-        std::cout << "[          ]   Early termination of test because vendor service cannot "
-                     "prepare model that it does not support."
-                  << std::endl;
-        return;
-    }
-    ASSERT_NE(nullptr, preparedModel.get());
 
     int example_no = 1;
     for (auto& example : examples) {
@@ -167,8 +124,8 @@
                 offset += i.location.length;
             }
         }
-        std::vector<hidl_memory> pools = {allocateSharedMemory(inputSize),
-                                          allocateSharedMemory(outputSize)};
+        std::vector<hidl_memory> pools = {nn::allocateSharedMemory(inputSize),
+                                          nn::allocateSharedMemory(outputSize)};
         ASSERT_NE(0ull, pools[INPUT].size());
         ASSERT_NE(0ull, pools[OUTPUT].size());
 
@@ -221,11 +178,107 @@
     }
 }
 
+void Execute(sp<V1_0::IDevice>& device, std::function<V1_0::Model(void)> create_model,
+             std::function<bool(int)> is_ignored,
+             const std::vector<MixedTypedExampleType>& examples) {
+    V1_0::Model model = create_model();
+
+    // see if service can handle model
+    bool fullySupportsModel = false;
+    ErrorStatus supportedStatus;
+    sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+    ASSERT_NE(nullptr, preparedModelCallback.get());
+
+    Return<void> supportedCall = device->getSupportedOperations(
+        model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
+            supportedStatus = status;
+            ASSERT_NE(0ul, supported.size());
+            fullySupportsModel =
+                std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
+        });
+    ASSERT_TRUE(supportedCall.isOk());
+    ASSERT_EQ(ErrorStatus::NONE, supportedStatus);
+    Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+    ASSERT_TRUE(prepareLaunchStatus.isOk());
+
+    // retrieve prepared model
+    preparedModelCallback->wait();
+    ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
+    sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
+    if (fullySupportsModel) {
+        EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
+    } else {
+        EXPECT_TRUE(prepareReturnStatus == ErrorStatus::NONE ||
+                    prepareReturnStatus == ErrorStatus::GENERAL_FAILURE);
+    }
+
+    // early termination if vendor service cannot fully prepare model
+    if (!fullySupportsModel && prepareReturnStatus == ErrorStatus::GENERAL_FAILURE) {
+        ASSERT_EQ(nullptr, preparedModel.get());
+        LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+                     "prepare model that it does not support.";
+        std::cout << "[          ]   Early termination of test because vendor service cannot "
+                     "prepare model that it does not support."
+                  << std::endl;
+        return;
+    }
+    ASSERT_NE(nullptr, preparedModel.get());
+
+    EvaluatePreparedModel(preparedModel, is_ignored, examples);
+}
+
+void Execute(sp<V1_1::IDevice>& device, std::function<V1_1::Model(void)> create_model,
+             std::function<bool(int)> is_ignored,
+             const std::vector<MixedTypedExampleType>& examples) {
+    V1_1::Model model = create_model();
+
+    // see if service can handle model
+    bool fullySupportsModel = false;
+    ErrorStatus supportedStatus;
+    sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
+    ASSERT_NE(nullptr, preparedModelCallback.get());
+
+    Return<void> supportedCall = device->getSupportedOperations_1_1(
+        model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
+            supportedStatus = status;
+            ASSERT_NE(0ul, supported.size());
+            fullySupportsModel =
+                std::all_of(supported.begin(), supported.end(), [](bool valid) { return valid; });
+        });
+    ASSERT_TRUE(supportedCall.isOk());
+    ASSERT_EQ(ErrorStatus::NONE, supportedStatus);
+    Return<ErrorStatus> prepareLaunchStatus =
+        device->prepareModel_1_1(model, preparedModelCallback);
+    ASSERT_TRUE(prepareLaunchStatus.isOk());
+
+    // retrieve prepared model
+    preparedModelCallback->wait();
+    ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
+    sp<IPreparedModel> preparedModel = preparedModelCallback->getPreparedModel();
+    if (fullySupportsModel) {
+        EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
+    } else {
+        EXPECT_TRUE(prepareReturnStatus == ErrorStatus::NONE ||
+                    prepareReturnStatus == ErrorStatus::GENERAL_FAILURE);
+    }
+
+    // early termination if vendor service cannot fully prepare model
+    if (!fullySupportsModel && prepareReturnStatus == ErrorStatus::GENERAL_FAILURE) {
+        ASSERT_EQ(nullptr, preparedModel.get());
+        LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+                     "prepare model that it does not support.";
+        std::cout << "[          ]   Early termination of test because vendor service cannot "
+                     "prepare model that it does not support."
+                  << std::endl;
+        return;
+    }
+    ASSERT_NE(nullptr, preparedModel.get());
+
+    EvaluatePreparedModel(preparedModel, is_ignored, examples);
+}
+
 }  // namespace generated_tests
 
-}  // namespace functional
-}  // namespace vts
-}  // namespace V1_0
 }  // namespace neuralnetworks
 }  // namespace hardware
 }  // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/Models.cpp b/neuralnetworks/1.0/vts/functional/Models.cpp
index 8ce4f25..180286a 100644
--- a/neuralnetworks/1.0/vts/functional/Models.cpp
+++ b/neuralnetworks/1.0/vts/functional/Models.cpp
@@ -17,19 +17,22 @@
 #define LOG_TAG "neuralnetworks_hidl_hal_test"
 
 #include "Models.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <hidlmemory/mapping.h>
 #include <vector>
 
+using ::android::sp;
+
 namespace android {
 namespace hardware {
 namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
 
 // create a valid model
-Model createValidTestModel() {
+V1_1::Model createValidTestModel_1_1() {
     const std::vector<float> operand2Data = {5.0f, 6.0f, 7.0f, 8.0f};
     const uint32_t size = operand2Data.size() * sizeof(float);
 
@@ -103,39 +106,34 @@
 }
 
 // create first invalid model
-Model createInvalidTestModel1() {
-    Model model = createValidTestModel();
+V1_1::Model createInvalidTestModel1_1_1() {
+    Model model = createValidTestModel_1_1();
     model.operations[0].type = static_cast<OperationType>(0xDEADBEEF); /* INVALID */
     return model;
 }
 
 // create second invalid model
-Model createInvalidTestModel2() {
-    Model model = createValidTestModel();
+V1_1::Model createInvalidTestModel2_1_1() {
+    Model model = createValidTestModel_1_1();
     const uint32_t operand1 = 0;
     const uint32_t operand5 = 4;  // INVALID OPERAND
     model.inputIndexes = std::vector<uint32_t>({operand1, operand5 /* INVALID OPERAND */});
     return model;
 }
 
-// allocator helper
-hidl_memory allocateSharedMemory(int64_t size, const std::string& type = "ashmem") {
-    hidl_memory memory;
+V1_0::Model createValidTestModel_1_0() {
+    V1_1::Model model = createValidTestModel_1_1();
+    return nn::convertToV1_0(model);
+}
 
-    sp<IAllocator> allocator = IAllocator::getService(type);
-    if (!allocator.get()) {
-        return {};
-    }
+V1_0::Model createInvalidTestModel1_1_0() {
+    V1_1::Model model = createInvalidTestModel1_1_1();
+    return nn::convertToV1_0(model);
+}
 
-    Return<void> ret = allocator->allocate(size, [&](bool success, const hidl_memory& mem) {
-        ASSERT_TRUE(success);
-        memory = mem;
-    });
-    if (!ret.isOk()) {
-        return {};
-    }
-
-    return memory;
+V1_0::Model createInvalidTestModel2_1_0() {
+    V1_1::Model model = createInvalidTestModel2_1_1();
+    return nn::convertToV1_0(model);
 }
 
 // create a valid request
@@ -154,8 +152,8 @@
     std::vector<RequestArgument> outputs = {{
         .location = {.poolIndex = OUTPUT, .offset = 0, .length = outputSize}, .dimensions = {},
     }};
-    std::vector<hidl_memory> pools = {allocateSharedMemory(inputSize),
-                                      allocateSharedMemory(outputSize)};
+    std::vector<hidl_memory> pools = {nn::allocateSharedMemory(inputSize),
+                                      nn::allocateSharedMemory(outputSize)};
     if (pools[INPUT].size() == 0 || pools[OUTPUT].size() == 0) {
         return {};
     }
@@ -199,9 +197,6 @@
     return request;
 }
 
-}  // namespace functional
-}  // namespace vts
-}  // namespace V1_0
 }  // namespace neuralnetworks
 }  // namespace hardware
 }  // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/Models.h b/neuralnetworks/1.0/vts/functional/Models.h
index e0d57d5..9398235 100644
--- a/neuralnetworks/1.0/vts/functional/Models.h
+++ b/neuralnetworks/1.0/vts/functional/Models.h
@@ -16,28 +16,27 @@
 
 #define LOG_TAG "neuralnetworks_hidl_hal_test"
 
-#include "VtsHalNeuralnetworksV1_0TargetTest.h"
+#include <android/hardware/neuralnetworks/1.1/types.h>
 
 namespace android {
 namespace hardware {
 namespace neuralnetworks {
-namespace V1_0 {
-namespace vts {
-namespace functional {
 
-// create the model
-Model createValidTestModel();
-Model createInvalidTestModel1();
-Model createInvalidTestModel2();
+// create V1_1 model
+V1_1::Model createValidTestModel_1_1();
+V1_1::Model createInvalidTestModel1_1_1();
+V1_1::Model createInvalidTestModel2_1_1();
+
+// create V1_0 model
+V1_0::Model createValidTestModel_1_0();
+V1_0::Model createInvalidTestModel1_1_0();
+V1_0::Model createInvalidTestModel2_1_0();
 
 // create the request
-Request createValidTestRequest();
-Request createInvalidTestRequest1();
-Request createInvalidTestRequest2();
+V1_0::Request createValidTestRequest();
+V1_0::Request createInvalidTestRequest1();
+V1_0::Request createInvalidTestRequest2();
 
-}  // namespace functional
-}  // namespace vts
-}  // namespace V1_0
 }  // namespace neuralnetworks
 }  // namespace hardware
 }  // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0.cpp
new file mode 100644
index 0000000..b14fb2c
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworksV1_0.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+
+using ::android::hardware::hidl_memory;
+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 {
+
+// allocator helper
+hidl_memory allocateSharedMemory(int64_t size) {
+    return nn::allocateSharedMemory(size);
+}
+
+// A class for test environment setup
+NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
+
+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<V1_0::IDevice>();
+}
+
+// The main test class for NEURALNETWORK HIDL HAL.
+NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
+
+void NeuralnetworksHidlTest::SetUp() {
+    device = ::testing::VtsHalHidlTargetTestBase::getService<V1_0::IDevice>(
+        NeuralnetworksHidlEnvironment::getInstance());
+    ASSERT_NE(nullptr, device.get());
+}
+
+void NeuralnetworksHidlTest::TearDown() {}
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_0
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0.h
similarity index 69%
rename from neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
rename to neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0.h
index 5cd209a..fbb1607 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,23 +29,6 @@
 #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::FusedActivationFunc;
-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 {
@@ -53,6 +36,8 @@
 namespace vts {
 namespace functional {
 
+hidl_memory allocateSharedMemory(int64_t size);
+
 // A class for test environment setup
 class NeuralnetworksHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
     NeuralnetworksHidlEnvironment();
@@ -74,25 +59,22 @@
     void SetUp() override;
     void TearDown() override;
 
-    sp<IPreparedModel> doPrepareModelShortcut();
-
-    sp<IDevice> device;
+    sp<V1_0::IDevice> device;
 };
-
 }  // namespace functional
 }  // namespace vts
 
 // pretty-print values for error messages
 
-template<typename CharT, typename Traits>
+template <typename CharT, typename Traits>
 ::std::basic_ostream<CharT, Traits>& operator<<(::std::basic_ostream<CharT, Traits>& os,
-                                                ErrorStatus errorStatus) {
+                                                V1_0::ErrorStatus errorStatus) {
     return os << toString(errorStatus);
 }
 
-template<typename CharT, typename Traits>
+template <typename CharT, typename Traits>
 ::std::basic_ostream<CharT, Traits>& operator<<(::std::basic_ostream<CharT, Traits>& os,
-                                                DeviceStatus deviceStatus) {
+                                                V1_0::DeviceStatus deviceStatus) {
     return os << toString(deviceStatus);
 }
 
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp
similarity index 80%
rename from neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
rename to neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp
index b99e20e..e838997 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0BasicTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "neuralnetworks_hidl_hal_test"
 
-#include "VtsHalNeuralnetworksV1_0TargetTest.h"
+#include "VtsHalNeuralnetworksV1_0.h"
 
 #include "Callbacks.h"
 #include "Models.h"
@@ -26,51 +26,34 @@
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <hidlmemory/mapping.h>
 
+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::FusedActivationFunc;
+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 {
-
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-using ::generated_tests::MixedTypedExampleType;
 
-namespace generated_tests {
-extern void Execute(const sp<IDevice>&, std::function<Model(void)>, std::function<bool(int)>,
-                    const std::vector<MixedTypedExampleType>&);
-}
-
-// A class for test environment setup
-NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
-
-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<IDevice>();
-}
-
-// The main test class for NEURALNETWORK HIDL HAL.
-NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
-
-void NeuralnetworksHidlTest::SetUp() {
-    device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
-        NeuralnetworksHidlEnvironment::getInstance());
-    ASSERT_NE(nullptr, device.get());
-}
-
-void NeuralnetworksHidlTest::TearDown() {}
-
-sp<IPreparedModel> NeuralnetworksHidlTest::doPrepareModelShortcut() {
-    Model model = createValidTestModel();
+inline sp<IPreparedModel> doPrepareModelShortcut(sp<IDevice>& device) {
+    Model model = createValidTestModel_1_0();
 
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     if (preparedModelCallback == nullptr) {
@@ -116,7 +99,7 @@
 
 // supported operations positive test
 TEST_F(NeuralnetworksHidlTest, SupportedOperationsPositiveTest) {
-    Model model = createValidTestModel();
+    Model model = createValidTestModel_1_0();
     Return<void> ret = device->getSupportedOperations(
         model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
             EXPECT_EQ(ErrorStatus::NONE, status);
@@ -127,7 +110,7 @@
 
 // supported operations negative test 1
 TEST_F(NeuralnetworksHidlTest, SupportedOperationsNegativeTest1) {
-    Model model = createInvalidTestModel1();
+    Model model = createInvalidTestModel1_1_0();
     Return<void> ret = device->getSupportedOperations(
         model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
             EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
@@ -138,7 +121,7 @@
 
 // supported operations negative test 2
 TEST_F(NeuralnetworksHidlTest, SupportedOperationsNegativeTest2) {
-    Model model = createInvalidTestModel2();
+    Model model = createInvalidTestModel2_1_0();
     Return<void> ret = device->getSupportedOperations(
         model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
             EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
@@ -149,7 +132,7 @@
 
 // prepare simple model positive test
 TEST_F(NeuralnetworksHidlTest, SimplePrepareModelPositiveTest) {
-    Model model = createValidTestModel();
+    Model model = createValidTestModel_1_0();
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     ASSERT_NE(nullptr, preparedModelCallback.get());
     Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
@@ -165,7 +148,7 @@
 
 // prepare simple model negative test 1
 TEST_F(NeuralnetworksHidlTest, SimplePrepareModelNegativeTest1) {
-    Model model = createInvalidTestModel1();
+    Model model = createInvalidTestModel1_1_0();
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     ASSERT_NE(nullptr, preparedModelCallback.get());
     Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
@@ -181,7 +164,7 @@
 
 // prepare simple model negative test 2
 TEST_F(NeuralnetworksHidlTest, SimplePrepareModelNegativeTest2) {
-    Model model = createInvalidTestModel2();
+    Model model = createInvalidTestModel2_1_0();
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     ASSERT_NE(nullptr, preparedModelCallback.get());
     Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
@@ -201,7 +184,7 @@
     std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
     const uint32_t OUTPUT = 1;
 
-    sp<IPreparedModel> preparedModel = doPrepareModelShortcut();
+    sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
     ASSERT_NE(nullptr, preparedModel.get());
     Request request = createValidTestRequest();
 
@@ -235,7 +218,7 @@
 
 // execute simple graph negative test 1
 TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest1) {
-    sp<IPreparedModel> preparedModel = doPrepareModelShortcut();
+    sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
     ASSERT_NE(nullptr, preparedModel.get());
     Request request = createInvalidTestRequest1();
 
@@ -252,7 +235,7 @@
 
 // execute simple graph negative test 2
 TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest2) {
-    sp<IPreparedModel> preparedModel = doPrepareModelShortcut();
+    sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
     ASSERT_NE(nullptr, preparedModel.get());
     Request request = createInvalidTestRequest2();
 
@@ -267,16 +250,6 @@
     EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, executionReturnStatus);
 }
 
-// Mixed-typed examples
-typedef MixedTypedExampleType MixedTypedExample;
-
-// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_vts_tests.cpp"
-
-// TODO: Add tests for execution failure, or wait_for/wait_until timeout.
-//       Discussion:
-//       https://googleplex-android-review.git.corp.google.com/#/c/platform/hardware/interfaces/+/2654636/5/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp@222
-
 }  // namespace functional
 }  // namespace vts
 }  // namespace V1_0
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0GeneratedTest.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0GeneratedTest.cpp
new file mode 100644
index 0000000..b99aef7
--- /dev/null
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0GeneratedTest.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworksV1_0.h"
+
+#include "Callbacks.h"
+#include "TestHarness.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+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::FusedActivationFunc;
+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 generated_tests {
+using ::generated_tests::MixedTypedExampleType;
+extern void Execute(sp<IDevice>&, std::function<Model(void)>, std::function<bool(int)>,
+                    const std::vector<MixedTypedExampleType>&);
+}  // namespace generated_tests
+
+namespace V1_0 {
+namespace vts {
+namespace functional {
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+
+// Mixed-typed examples
+typedef generated_tests::MixedTypedExampleType MixedTypedExample;
+
+// in frameworks/ml/nn/runtime/tests/generated/
+#include "all_generated_V1_0_vts_tests.cpp"
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_0
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.1/types.hal b/neuralnetworks/1.1/types.hal
index 18863d3..fae5dd0 100644
--- a/neuralnetworks/1.1/types.hal
+++ b/neuralnetworks/1.1/types.hal
@@ -330,4 +330,12 @@
      * equals OperandLifeTime::CONSTANT_REFERENCE.
      */
     vec<memory> pools;
+
+    /**
+     * 'true' indicates TENSOR_FLOAT32 may be calculated with range and/or
+     * precision as low as that of the IEEE 754 16-bit floating-point format.
+     * 'false' indicates TENSOR_FLOAT32 must be calculated using at least the
+     * range and precision of the IEEE 754 32-bit floating-point format.
+     */
+    bool relaxComputationFloat32toFloat16;
 };
diff --git a/neuralnetworks/1.1/vts/OWNERS b/neuralnetworks/1.1/vts/OWNERS
new file mode 100644
index 0000000..7f75ab3
--- /dev/null
+++ b/neuralnetworks/1.1/vts/OWNERS
@@ -0,0 +1,10 @@
+# Neuralnetworks team
+butlermichael@google.com
+dgross@google.com
+jeanluc@google.com
+miaowang@google.com
+yangni@google.com
+
+# VTS team
+yim@google.com
+yuexima@google.com
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..623b441
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+    name: "VtsHalNeuralnetworksV1_1TargetTest",
+    srcs: [
+        "VtsHalNeuralnetworksV1_1.cpp",
+        "VtsHalNeuralnetworksV1_1BasicTest.cpp",
+        "VtsHalNeuralnetworksV1_1GeneratedTest.cpp",
+    ],
+    defaults: ["VtsHalTargetTestDefaults"],
+    static_libs: [
+        "android.hardware.neuralnetworks@1.0",
+        "android.hardware.neuralnetworks@1.1",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libhidlmemory",
+        "libneuralnetworks_utils",
+        "VtsHalNeuralnetworksTest_utils",
+    ],
+    header_libs: [
+        "libneuralnetworks_headers",
+        "libneuralnetworks_generated_test_harness_headers",
+        "libneuralnetworks_generated_tests",
+    ],
+}
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1.cpp
new file mode 100644
index 0000000..b1d3be7
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworksV1_1.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+#include <hidlmemory/mapping.h>
+
+using ::android::hardware::hidl_memory;
+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_1 {
+namespace vts {
+namespace functional {
+
+// allocator helper
+hidl_memory allocateSharedMemory(int64_t size) {
+    return nn::allocateSharedMemory(size);
+}
+
+// A class for test environment setup
+NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
+
+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<V1_1::IDevice>();
+}
+
+// The main test class for NEURALNETWORK HIDL HAL.
+NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
+
+void NeuralnetworksHidlTest::SetUp() {
+    device = ::testing::VtsHalHidlTargetTestBase::getService<V1_1::IDevice>(
+        NeuralnetworksHidlEnvironment::getInstance());
+    ASSERT_NE(nullptr, device.get());
+}
+
+void NeuralnetworksHidlTest::TearDown() {}
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1.h
similarity index 61%
copy from neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
copy to neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1.h
index 5cd209a..426246c 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.h
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
-#define VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
+#ifndef VTS_HAL_NEURALNETWORKS_V1_1_H
+#define VTS_HAL_NEURALNETWORKS_V1_1_H
 
-#include <android/hardware/neuralnetworks/1.0/IDevice.h>
 #include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
 #include <android/hardware/neuralnetworks/1.0/IPreparedModel.h>
 #include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
-#include <android/hardware/neuralnetworks/1.0/types.h>
+#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
 #include <android/hidl/allocator/1.0/IAllocator.h>
 
 #include <VtsHalHidlTargetTestBase.h>
@@ -29,29 +29,13 @@
 #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::FusedActivationFunc;
-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 V1_1 {
 namespace vts {
 namespace functional {
+hidl_memory allocateSharedMemory(int64_t size);
 
 // A class for test environment setup
 class NeuralnetworksHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
@@ -74,31 +58,28 @@
     void SetUp() override;
     void TearDown() override;
 
-    sp<IPreparedModel> doPrepareModelShortcut();
-
-    sp<IDevice> device;
+    sp<V1_1::IDevice> device;
 };
-
 }  // namespace functional
 }  // namespace vts
 
 // pretty-print values for error messages
 
-template<typename CharT, typename Traits>
+template <typename CharT, typename Traits>
 ::std::basic_ostream<CharT, Traits>& operator<<(::std::basic_ostream<CharT, Traits>& os,
-                                                ErrorStatus errorStatus) {
+                                                V1_0::ErrorStatus errorStatus) {
     return os << toString(errorStatus);
 }
 
-template<typename CharT, typename Traits>
+template <typename CharT, typename Traits>
 ::std::basic_ostream<CharT, Traits>& operator<<(::std::basic_ostream<CharT, Traits>& os,
-                                                DeviceStatus deviceStatus) {
+                                                V1_0::DeviceStatus deviceStatus) {
     return os << toString(deviceStatus);
 }
 
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace neuralnetworks
 }  // namespace hardware
 }  // namespace android
 
-#endif  // VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
+#endif  // VTS_HAL_NEURALNETWORKS_V1_1_H
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp
similarity index 74%
copy from neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
copy to neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp
index b99e20e..51eff2a 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1BasicTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,67 +16,58 @@
 
 #define LOG_TAG "neuralnetworks_hidl_hal_test"
 
-#include "VtsHalNeuralnetworksV1_0TargetTest.h"
+#include "VtsHalNeuralnetworksV1_1.h"
 
 #include "Callbacks.h"
 #include "Models.h"
 #include "TestHarness.h"
 
 #include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <hidlmemory/mapping.h>
 
+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::ErrorStatus;
+using ::android::hardware::neuralnetworks::V1_0::FusedActivationFunc;
+using ::android::hardware::neuralnetworks::V1_0::Operand;
+using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
+using ::android::hardware::neuralnetworks::V1_0::OperandType;
+using ::android::hardware::neuralnetworks::V1_0::Request;
+using ::android::hardware::neuralnetworks::V1_1::IDevice;
+using ::android::hardware::neuralnetworks::V1_1::Model;
+using ::android::hardware::neuralnetworks::V1_1::Operation;
+using ::android::hardware::neuralnetworks::V1_1::OperationType;
+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 V1_1 {
 namespace vts {
 namespace functional {
-
 using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
 using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
-using ::generated_tests::MixedTypedExampleType;
 
-namespace generated_tests {
-extern void Execute(const sp<IDevice>&, std::function<Model(void)>, std::function<bool(int)>,
-                    const std::vector<MixedTypedExampleType>&);
-}
-
-// A class for test environment setup
-NeuralnetworksHidlEnvironment::NeuralnetworksHidlEnvironment() {}
-
-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<IDevice>();
-}
-
-// The main test class for NEURALNETWORK HIDL HAL.
-NeuralnetworksHidlTest::~NeuralnetworksHidlTest() {}
-
-void NeuralnetworksHidlTest::SetUp() {
-    device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
-        NeuralnetworksHidlEnvironment::getInstance());
-    ASSERT_NE(nullptr, device.get());
-}
-
-void NeuralnetworksHidlTest::TearDown() {}
-
-sp<IPreparedModel> NeuralnetworksHidlTest::doPrepareModelShortcut() {
-    Model model = createValidTestModel();
+inline sp<IPreparedModel> doPrepareModelShortcut(sp<IDevice>& device) {
+    Model model = createValidTestModel_1_1();
 
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     if (preparedModelCallback == nullptr) {
         return nullptr;
     }
-    Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+    Return<ErrorStatus> prepareLaunchStatus =
+        device->prepareModel_1_1(model, preparedModelCallback);
     if (!prepareLaunchStatus.isOk() || prepareLaunchStatus != ErrorStatus::NONE) {
         return nullptr;
     }
@@ -116,8 +107,8 @@
 
 // supported operations positive test
 TEST_F(NeuralnetworksHidlTest, SupportedOperationsPositiveTest) {
-    Model model = createValidTestModel();
-    Return<void> ret = device->getSupportedOperations(
+    Model model = createValidTestModel_1_1();
+    Return<void> ret = device->getSupportedOperations_1_1(
         model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
             EXPECT_EQ(ErrorStatus::NONE, status);
             EXPECT_EQ(model.operations.size(), supported.size());
@@ -127,8 +118,8 @@
 
 // supported operations negative test 1
 TEST_F(NeuralnetworksHidlTest, SupportedOperationsNegativeTest1) {
-    Model model = createInvalidTestModel1();
-    Return<void> ret = device->getSupportedOperations(
+    Model model = createInvalidTestModel1_1_1();
+    Return<void> ret = device->getSupportedOperations_1_1(
         model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
             EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
             (void)supported;
@@ -138,8 +129,8 @@
 
 // supported operations negative test 2
 TEST_F(NeuralnetworksHidlTest, SupportedOperationsNegativeTest2) {
-    Model model = createInvalidTestModel2();
-    Return<void> ret = device->getSupportedOperations(
+    Model model = createInvalidTestModel2_1_1();
+    Return<void> ret = device->getSupportedOperations_1_1(
         model, [&](ErrorStatus status, const hidl_vec<bool>& supported) {
             EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
             (void)supported;
@@ -149,10 +140,11 @@
 
 // prepare simple model positive test
 TEST_F(NeuralnetworksHidlTest, SimplePrepareModelPositiveTest) {
-    Model model = createValidTestModel();
+    Model model = createValidTestModel_1_1();
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     ASSERT_NE(nullptr, preparedModelCallback.get());
-    Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+    Return<ErrorStatus> prepareLaunchStatus =
+        device->prepareModel_1_1(model, preparedModelCallback);
     ASSERT_TRUE(prepareLaunchStatus.isOk());
     EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(prepareLaunchStatus));
 
@@ -165,10 +157,11 @@
 
 // prepare simple model negative test 1
 TEST_F(NeuralnetworksHidlTest, SimplePrepareModelNegativeTest1) {
-    Model model = createInvalidTestModel1();
+    Model model = createInvalidTestModel1_1_1();
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     ASSERT_NE(nullptr, preparedModelCallback.get());
-    Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+    Return<ErrorStatus> prepareLaunchStatus =
+        device->prepareModel_1_1(model, preparedModelCallback);
     ASSERT_TRUE(prepareLaunchStatus.isOk());
     EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(prepareLaunchStatus));
 
@@ -181,10 +174,11 @@
 
 // prepare simple model negative test 2
 TEST_F(NeuralnetworksHidlTest, SimplePrepareModelNegativeTest2) {
-    Model model = createInvalidTestModel2();
+    Model model = createInvalidTestModel2_1_1();
     sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
     ASSERT_NE(nullptr, preparedModelCallback.get());
-    Return<ErrorStatus> prepareLaunchStatus = device->prepareModel(model, preparedModelCallback);
+    Return<ErrorStatus> prepareLaunchStatus =
+        device->prepareModel_1_1(model, preparedModelCallback);
     ASSERT_TRUE(prepareLaunchStatus.isOk());
     EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(prepareLaunchStatus));
 
@@ -201,7 +195,7 @@
     std::vector<float> expectedData = {6.0f, 8.0f, 10.0f, 12.0f};
     const uint32_t OUTPUT = 1;
 
-    sp<IPreparedModel> preparedModel = doPrepareModelShortcut();
+    sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
     ASSERT_NE(nullptr, preparedModel.get());
     Request request = createValidTestRequest();
 
@@ -235,7 +229,7 @@
 
 // execute simple graph negative test 1
 TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest1) {
-    sp<IPreparedModel> preparedModel = doPrepareModelShortcut();
+    sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
     ASSERT_NE(nullptr, preparedModel.get());
     Request request = createInvalidTestRequest1();
 
@@ -252,7 +246,7 @@
 
 // execute simple graph negative test 2
 TEST_F(NeuralnetworksHidlTest, SimpleExecuteGraphNegativeTest2) {
-    sp<IPreparedModel> preparedModel = doPrepareModelShortcut();
+    sp<IPreparedModel> preparedModel = doPrepareModelShortcut(device);
     ASSERT_NE(nullptr, preparedModel.get());
     Request request = createInvalidTestRequest2();
 
@@ -267,24 +261,14 @@
     EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, executionReturnStatus);
 }
 
-// Mixed-typed examples
-typedef MixedTypedExampleType MixedTypedExample;
-
-// in frameworks/ml/nn/runtime/tests/generated/
-#include "all_generated_vts_tests.cpp"
-
-// TODO: Add tests for execution failure, or wait_for/wait_until timeout.
-//       Discussion:
-//       https://googleplex-android-review.git.corp.google.com/#/c/platform/hardware/interfaces/+/2654636/5/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworksV1_0TargetTest.cpp@222
-
 }  // namespace functional
 }  // namespace vts
-}  // namespace V1_0
+}  // namespace V1_1
 }  // namespace neuralnetworks
 }  // namespace hardware
 }  // namespace android
 
-using android::hardware::neuralnetworks::V1_0::vts::functional::NeuralnetworksHidlEnvironment;
+using android::hardware::neuralnetworks::V1_1::vts::functional::NeuralnetworksHidlEnvironment;
 
 int main(int argc, char** argv) {
     ::testing::AddGlobalTestEnvironment(NeuralnetworksHidlEnvironment::getInstance());
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1GeneratedTest.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1GeneratedTest.cpp
new file mode 100644
index 0000000..025d9fe
--- /dev/null
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworksV1_1GeneratedTest.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "neuralnetworks_hidl_hal_test"
+
+#include "VtsHalNeuralnetworksV1_1.h"
+
+#include "Callbacks.h"
+#include "TestHarness.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/neuralnetworks/1.1/IDevice.h>
+#include <android/hardware/neuralnetworks/1.1/types.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+
+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::ErrorStatus;
+using ::android::hardware::neuralnetworks::V1_0::FusedActivationFunc;
+using ::android::hardware::neuralnetworks::V1_0::Operand;
+using ::android::hardware::neuralnetworks::V1_0::OperandLifeTime;
+using ::android::hardware::neuralnetworks::V1_0::OperandType;
+using ::android::hardware::neuralnetworks::V1_0::Request;
+using ::android::hardware::neuralnetworks::V1_1::IDevice;
+using ::android::hardware::neuralnetworks::V1_1::Model;
+using ::android::hardware::neuralnetworks::V1_1::Operation;
+using ::android::hardware::neuralnetworks::V1_1::OperationType;
+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 generated_tests {
+using ::generated_tests::MixedTypedExampleType;
+extern void Execute(sp<V1_1::IDevice>&, std::function<Model(void)>, std::function<bool(int)>,
+                    const std::vector<MixedTypedExampleType>&);
+}  // namespace generated_tests
+
+namespace V1_1 {
+namespace vts {
+namespace functional {
+using ::android::hardware::neuralnetworks::V1_0::implementation::ExecutionCallback;
+using ::android::hardware::neuralnetworks::V1_0::implementation::PreparedModelCallback;
+
+// Mixed-typed examples
+typedef generated_tests::MixedTypedExampleType MixedTypedExample;
+
+// in frameworks/ml/nn/runtime/tests/generated/
+#include "all_generated_V1_0_vts_tests.cpp"
+#include "all_generated_V1_1_vts_tests.cpp"
+
+}  // namespace functional
+}  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index 2f00fbb..e17c961 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -24,6 +24,7 @@
 
 #include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::hardware::nfc::V1_0::INfc;
 using ::android::hardware::nfc::V1_0::INfcClientCallback;
@@ -93,11 +94,26 @@
     };
 };
 
+// Test environment for Nfc HIDL HAL.
+class NfcHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+  // get the test environment singleton
+  static NfcHidlEnvironment* Instance() {
+    static NfcHidlEnvironment* instance = new NfcHidlEnvironment;
+    return instance;
+  }
+
+  virtual void registerTestServices() override { registerTestService<INfc>(); }
+ private:
+  NfcHidlEnvironment() {}
+};
+
 // The main test class for NFC HIDL HAL.
 class NfcHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
   virtual void SetUp() override {
-    nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>();
+    nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>(
+        NfcHidlEnvironment::Instance()->getServiceName<INfc>());
     ASSERT_NE(nfc_, nullptr);
 
     nfc_cb_ = new NfcClientCallback();
@@ -163,15 +179,6 @@
   sp<NfcClientCallback> nfc_cb_;
 };
 
-// A class for test environment setup (kept since this file is a template).
-class NfcHidlEnvironment : public ::testing::Environment {
- public:
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-
- private:
-};
-
 /*
  * OpenAndClose:
  * Makes an open call, waits for NfcEvent.OPEN_CPLT
@@ -586,8 +593,9 @@
 }
 
 int main(int argc, char** argv) {
-  ::testing::AddGlobalTestEnvironment(new NfcHidlEnvironment);
+  ::testing::AddGlobalTestEnvironment(NfcHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
+  NfcHidlEnvironment::Instance()->init(&argc, argv);
 
   std::system("svc nfc disable"); /* Turn off NFC */
   sleep(5);
diff --git a/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp b/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
index a5b40d4..bef412b 100644
--- a/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
+++ b/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
@@ -25,6 +25,7 @@
 
 #include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::hardware::nfc::V1_1::INfc;
 using ::android::hardware::nfc::V1_1::INfcClientCallback;
@@ -78,6 +79,20 @@
     };
 };
 
+// Test environment for Nfc HIDL HAL.
+class NfcHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static NfcHidlEnvironment* Instance() {
+        static NfcHidlEnvironment* instance = new NfcHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<INfc>(); }
+   private:
+    NfcHidlEnvironment() {}
+};
+
 // The main test class for NFC HIDL HAL.
 class NfcHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    public:
@@ -127,15 +142,6 @@
     sp<NfcClientCallback> nfc_cb_;
 };
 
-// A class for test environment setup (kept since this file is a template).
-class NfcHidlEnvironment : public ::testing::Environment {
-   public:
-    virtual void SetUp() {}
-    virtual void TearDown() {}
-
-   private:
-};
-
 /*
  * factoryReset
  * calls factoryReset()
@@ -204,8 +210,9 @@
 }
 
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(new NfcHidlEnvironment);
+    ::testing::AddGlobalTestEnvironment(NfcHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
+    NfcHidlEnvironment::Instance()->init(&argc, argv);
 
     std::system("svc nfc disable"); /* Turn off NFC */
     sleep(5);
diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal
index 4d22bc0..6787a82 100644
--- a/radio/1.0/types.hal
+++ b/radio/1.0/types.hal
@@ -1292,10 +1292,9 @@
                                           // from cell to device.
                                           // Approximate distance is calculated using
                                           // 300m/us * timingAdvance.
-                                          // Range: 0 to 0x7FFFFFFE
-                                          // INT_MAX : 0x7FFFFFFF denotes invalid value.
-                                          // Reference: 3GPP 36.321 section 6.1.3.5
-                                          // also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html
+                                          // Range: 0 to 1282 inclusive.
+                                          // INT_MAX : 0x7FFFFFFF denotes unknown value.
+                                          // Reference: 3GPP 36.213 section 4.2.3
 };
 
 struct TdScdmaSignalStrength {
diff --git a/radio/1.2/Android.bp b/radio/1.2/Android.bp
index 48ac5a1..a9c80b7 100644
--- a/radio/1.2/Android.bp
+++ b/radio/1.2/Android.bp
@@ -28,11 +28,13 @@
         "CellIdentityGsm",
         "CellIdentityLte",
         "CellIdentityOperatorNames",
+        "CellIdentityTdscdma",
         "CellIdentityWcdma",
         "CellInfo",
         "CellInfoCdma",
         "CellInfoGsm",
         "CellInfoLte",
+        "CellInfoTdscdma",
         "CellInfoWcdma",
         "DataRequestReason",
         "IncrementalResultsPeriodicityRange",
@@ -44,6 +46,9 @@
         "PhysicalChannelConfig",
         "RadioConst",
         "ScanIntervalRange",
+        "SignalStrength",
+        "TdscdmaSignalStrength",
+        "WcdmaSignalStrength",
     ],
     gen_java: true,
 }
diff --git a/radio/1.2/IRadio.hal b/radio/1.2/IRadio.hal
index 67ce56c..6463b0f 100644
--- a/radio/1.2/IRadio.hal
+++ b/radio/1.2/IRadio.hal
@@ -50,7 +50,7 @@
      *
      * @param serial Serial number of request.
      * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the
-     *        indications are enabled. See @1.2::IndicationFilter for the definition of each bit.
+     *     indications are enabled. See @1.2::IndicationFilter for the definition of each bit.
      *
      * Response callback is IRadioResponse.setIndicationFilterResponse()
      */
@@ -68,16 +68,16 @@
      *
      * @param serial Serial number of request.
      * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0
-     *                     disables hysteresis.
+     *     disables hysteresis.
      * @param hysteresisDb An interval in dB defining the required magnitude change between reports.
-     *                     hysteresisDb must be smaller than the smallest threshold delta. An
-     *                     interval value of 0 disables hysteresis.
+     *     hysteresisDb must be smaller than the smallest threshold delta. An
+     *     interval value of 0 disables hysteresis.
      * @param thresholdsDbm A vector of trigger thresholds in dBm. A vector size of 0 disables the
-     *                      use of thresholds for reporting.
-     * @param ran The type of network for which to apply these thresholds.
+     *     use of thresholds for reporting.
+     * @param accessNetwork The type of network for which to apply these thresholds.
      */
     oneway setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs,
-            int32_t hysteresisDb, vec<int32_t> thresholdsDbm, RadioAccessNetworks ran);
+            int32_t hysteresisDb, vec<int32_t> thresholdsDbm, AccessNetwork accessNetwork);
 
     /**
      * Sets the link capacity reporting criteria.
@@ -91,23 +91,22 @@
      *
      * @param serial Serial number of request.
      * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0
-     *                     disables hysteresis.
+     *     disables hysteresis.
      * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL
-     *                         reports. hysteresisDlKbps must be smaller than the smallest threshold
-     *                         delta. A value of 0 disables hysteresis.
+     *     reports. hysteresisDlKbps must be smaller than the smallest threshold delta. A value of 0
+     *     disables hysteresis.
      * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL
-     *                         reports. hysteresisUlKbps must be smaller than the smallest threshold
-     *                         delta. A value of 0 disables hysteresis.
+     *     reports. hysteresisUlKbps must be smaller than the smallest threshold delta. A value of 0
+     *     disables hysteresis.
      * @param thresholdsDownlinkKbps A vector of trigger thresholds in kbps for downlink reports. A
-     *                               vector size of 0 disables the use of DL thresholds for
-     *                               reporting.
+     *     vector size of 0 disables the use of DL thresholds for reporting.
      * @param thresholdsUplinkKbps A vector of trigger thresholds in kbps for uplink reports. A
-     *                             vector size of 0 disables the use of UL thresholds for reporting.
-     * @param ran The type of network for which to apply these thresholds.
+     *     vector size of 0 disables the use of UL thresholds for reporting.
+     * @param accessNetwork The type of network for which to apply these thresholds.
      */
     oneway setLinkCapacityReportingCriteria(int32_t serial, int32_t hysteresisMs,
             int32_t hysteresisDlKbps, int32_t hysteresisUlKbps, vec<int32_t> thresholdsDownlinkKbps,
-            vec<int32_t> thresholdsUplinkKbps, RadioAccessNetworks ran);
+            vec<int32_t> thresholdsUplinkKbps, AccessNetwork accessNetwork);
 
     /**
      * Setup a packet data connection. If DataCallResponse.status returns DataCallFailCause:NONE,
diff --git a/radio/1.2/IRadioIndication.hal b/radio/1.2/IRadioIndication.hal
index a124557..3d93b98 100644
--- a/radio/1.2/IRadioIndication.hal
+++ b/radio/1.2/IRadioIndication.hal
@@ -34,7 +34,7 @@
      * Same information as returned by getCellInfoList() in 1.0::IRadio.
      *
      * @param type Type of radio indication
-     * @param records Current cell information known to radio
+     * @param records Current cell information
      */
      oneway cellInfoList_1_2(RadioIndicationType type, vec<CellInfo> records);
 
@@ -50,7 +50,7 @@
      * suppressed by @1.2::IRadio.setIndicationFilter_1_2().
      *
      * @param type Type of radio indication
-     * @param lce LinkCapacityEstimate information as defined in types.hal
+     * @param lce LinkCapacityEstimate
      */
     oneway currentLinkCapacityEstimate(RadioIndicationType type, LinkCapacityEstimate lce);
 
@@ -58,8 +58,16 @@
      * Indicates physical channel configurations.
      *
      * @param type Type of radio indication
-     * @param configs List of PhysicalChannelConfigs as defined in types.hal
+     * @param configs Vector of PhysicalChannelConfigs
      */
     oneway currentPhysicalChannelConfigs(RadioIndicationType type,
             vec<PhysicalChannelConfig> configs);
+
+    /**
+     * Indicates current signal strength of the radio.
+     *
+     * @param type Type of radio indication
+     * @param signalStrength SignalStrength information
+     */
+    oneway currentSignalStrength_1_2(RadioIndicationType type, SignalStrength signalStrength);
 };
diff --git a/radio/1.2/IRadioResponse.hal b/radio/1.2/IRadioResponse.hal
index 93ec4d7..f26c9ec 100644
--- a/radio/1.2/IRadioResponse.hal
+++ b/radio/1.2/IRadioResponse.hal
@@ -88,4 +88,14 @@
      *   RadioError:CANCELLED
      */
     oneway getCurrentCallsResponse_1_2(RadioResponseInfo info, vec<Call> calls);
+
+    /**
+     * @param signalStrength Current signal strength
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     */
+    oneway getSignalStrengthResponse_1_2(RadioResponseInfo info, SignalStrength signalStrength);
 };
diff --git a/radio/1.2/types.hal b/radio/1.2/types.hal
index c353645..b68895e 100644
--- a/radio/1.2/types.hal
+++ b/radio/1.2/types.hal
@@ -17,12 +17,13 @@
 package android.hardware.radio@1.2;
 
 import @1.0::Call;
-import @1.0::CdmaSignalStrength;
 import @1.0::CardState;
 import @1.0::CardStatus;
+import @1.0::CdmaSignalStrength;
 import @1.0::CellIdentityCdma;
 import @1.0::CellIdentityGsm;
 import @1.0::CellIdentityLte;
+import @1.0::CellIdentityTdscdma;
 import @1.0::CellIdentityWcdma;
 import @1.0::CellInfoTdscdma;
 import @1.0::CellInfoType;
@@ -30,10 +31,12 @@
 import @1.0::GsmSignalStrength;
 import @1.0::LteSignalStrength;
 import @1.0::RadioConst;
+import @1.0::RadioError;
+import @1.0::SignalStrength;
+import @1.0::TdScdmaSignalStrength;
 import @1.0::TimeStampType;
 import @1.0::WcdmaSignalStrength;
 import @1.1::RadioAccessSpecifier;
-import @1.0::RadioError;
 import @1.1::ScanStatus;
 import @1.1::ScanType;
 
@@ -251,6 +254,15 @@
     int32_t bandwidth;
 };
 
+struct CellIdentityTdscdma {
+    @1.0::CellIdentityTdscdma base;
+    /**
+     * 16-bit UMTS Absolute RF Channel Number defined in TS 25.102 5.4.4; this value must be valid.
+     */
+    int32_t uarfcn;
+    CellIdentityOperatorNames operatorNames;
+};
+
 struct CellIdentityWcdma {
     @1.0::CellIdentityWcdma base;
     CellIdentityOperatorNames operatorNames;
@@ -277,6 +289,11 @@
     LteSignalStrength signalStrengthLte;
 };
 
+struct CellInfoTdscdma {
+    CellIdentityTdscdma cellIdentityTdscdma;
+    TdscdmaSignalStrength signalStrengthTdscdma;
+};
+
 struct CellInfo {
     /**
      * Cell type for selecting from union CellInfo.
@@ -344,11 +361,17 @@
 
 struct LinkCapacityEstimate {
     /**
-     * Estimated downlink capacity in kbps.
+     * Estimated downlink capacity in kbps. This bandwidth estimate shall be the estimated
+     * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
+     * If the DL Aggregate Maximum Bit Rate is known, this value shall not exceed the DL-AMBR
+     * for the Internet PDN connection.
      */
     uint32_t downlinkCapacityKbps;
     /**
-     * Estimated uplink capacity in kbps.
+     * Estimated uplink capacity in kbps. This bandwidth estimate shall be the estimated
+     * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
+     * If the UL Aggregate Maximum Bit Rate is known, this value shall not exceed the UL-AMBR
+     * for the Internet PDN connection.
      */
     uint32_t uplinkCapacityKbps;
 };
@@ -397,3 +420,45 @@
     @1.0::Call base;
     AudioQuality audioQuality;
 };
+
+struct WcdmaSignalStrength {
+    @1.0::WcdmaSignalStrength base;
+    /**
+     * CPICH RSCP as defined in TS 25.215 5.1.1
+     * Valid values are (0-96, 255) as defined in TS 27.007 8.69
+     */
+    uint32_t rscp;
+    /**
+     * Ec/No value as defined in TS 25.215 5.1.5
+     * Valid values are (0-49, 255) as defined in TS 27.007 8.69
+     */
+    uint32_t ecno;
+
+};
+
+struct TdscdmaSignalStrength {
+    /**
+     * UTRA carrier RSSI as defined in TS 25.225 5.1.4
+     * Valid values are (0-96, 99) as defined in TS 27.007 8.69
+     */
+    uint32_t signalStrength;
+    /**
+     * Transport Channel BER as defined in TS 25.225 5.2.5
+     * Valid values are (0-49, 99) as defined in TS 27.007 8.69
+     */
+    uint32_t bitErrorRate;
+    /**
+     * P-CCPCH RSCP as defined in TS 25.225 5.1.1
+     * Valid values are (0-96, 255) as defined in TS 27.007 8.69
+     */
+    uint32_t rscp;
+};
+
+struct SignalStrength {
+    GsmSignalStrength gsm;
+    CdmaSignalStrength cdma;
+    EvdoSignalStrength evdo;
+    LteSignalStrength lte;
+    TdScdmaSignalStrength tdScdma;
+    WcdmaSignalStrength wcdma;
+};
diff --git a/thermal/1.0/vts/functional/VtsHalThermalV1_0TargetTest.cpp b/thermal/1.0/vts/functional/VtsHalThermalV1_0TargetTest.cpp
index dfa11a1..6f059ef 100644
--- a/thermal/1.0/vts/functional/VtsHalThermalV1_0TargetTest.cpp
+++ b/thermal/1.0/vts/functional/VtsHalThermalV1_0TargetTest.cpp
@@ -21,10 +21,11 @@
 
 #define LOG_TAG "thermal_hidl_hal_test"
 
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/thermal/1.0/IThermal.h>
 #include <android/hardware/thermal/1.0/types.h>
-#include <VtsHalHidlTargetTestBase.h>
 #include <unistd.h>
 
 using ::android::hardware::hidl_string;
@@ -45,11 +46,26 @@
 #define MAX_DEVICE_TEMPERATURE 200
 #define MAX_FAN_SPEED 20000
 
+// Test environment for Thermal HIDL HAL.
+class ThermalHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+  // get the test environment singleton
+  static ThermalHidlEnvironment* Instance() {
+    static ThermalHidlEnvironment* instance = new ThermalHidlEnvironment;
+    return instance;
+  }
+
+  virtual void registerTestServices() override { registerTestService<IThermal>(); }
+ private:
+  ThermalHidlEnvironment() {}
+};
+
 // The main test class for THERMAL HIDL HAL.
 class ThermalHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
   virtual void SetUp() override {
-    thermal_ = ::testing::VtsHalHidlTargetTestBase::getService<IThermal>();
+    thermal_ = ::testing::VtsHalHidlTargetTestBase::getService<IThermal>(
+        ThermalHidlEnvironment::Instance()->getServiceName<IThermal>());
     ASSERT_NE(thermal_, nullptr);
     baseSize_ = 0;
     names_.clear();
@@ -207,7 +223,9 @@
 }
 
 int main(int argc, char** argv) {
+  ::testing::AddGlobalTestEnvironment(ThermalHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
+  ThermalHidlEnvironment::Instance()->init(&argc, argv);
   int status = RUN_ALL_TESTS();
   LOG(INFO) << "Test result = " << status;
   return status;
diff --git a/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp b/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp
index 6c1599b..91c8b6e 100644
--- a/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp
+++ b/thermal/1.1/vts/functional/VtsHalThermalV1_1TargetTest.cpp
@@ -20,6 +20,7 @@
 
 #include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::hardware::thermal::V1_0::Temperature;
 using ::android::hardware::thermal::V1_0::TemperatureType;
@@ -62,11 +63,26 @@
     }
 };
 
+// Test environment for Thermal HIDL HAL.
+class ThermalHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static ThermalHidlEnvironment* Instance() {
+        static ThermalHidlEnvironment* instance = new ThermalHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IThermal>(); }
+   private:
+    ThermalHidlEnvironment() {}
+};
+
 // 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>();
+        mThermal = ::testing::VtsHalHidlTargetTestBase::getService<IThermal>(
+            ThermalHidlEnvironment::Instance()->getServiceName<IThermal>());
         ASSERT_NE(mThermal, nullptr);
         mThermalCallback = new(std::nothrow) ThermalCallback();
         ASSERT_NE(mThermalCallback, nullptr);
@@ -99,7 +115,9 @@
 }
 
 int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(ThermalHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
+    ThermalHidlEnvironment::Instance()->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     cout << "Test result = " << status << std::endl;
     return status;
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index ea27f02..b2f76a3 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -20,7 +20,8 @@
     srcs: [
         "wifi_hidl_call_util_selftest.cpp",
         "wifi_hidl_test.cpp",
-        "wifi_hidl_test_utils.cpp"],
+        "wifi_hidl_test_utils.cpp",
+    ],
     export_include_dirs: [
         "."
     ],
diff --git a/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp b/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
index beac039..e7b8593 100644
--- a/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
+++ b/wifi/1.0/vts/functional/VtsHalWifiV1_0TargetTest.cpp
@@ -16,16 +16,31 @@
 
 #include <android-base/logging.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-
 #include "wifi_hidl_test_utils.h"
 
-WifiHidlEnvironment* gEnv;
+class WifiVtsHidlEnvironment_1_0 : public WifiHidlEnvironment {
+   public:
+    // get the test environment singleton
+    static WifiVtsHidlEnvironment_1_0* Instance() {
+        static WifiVtsHidlEnvironment_1_0* instance =
+            new WifiVtsHidlEnvironment_1_0;
+        return instance;
+    }
+
+    virtual void registerTestServices() override {
+        registerTestService<android::hardware::wifi::V1_0::IWifi>();
+    }
+
+   private:
+    WifiVtsHidlEnvironment_1_0() {}
+};
+
+WifiHidlEnvironment* gEnv = WifiVtsHidlEnvironment_1_0::Instance();
 
 int main(int argc, char** argv) {
-    gEnv = new WifiHidlEnvironment();
     ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
         status = RUN_ALL_TESTS();
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 313bdd8..97a371b 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -35,6 +35,8 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 
+extern WifiHidlEnvironment* gEnv;
+
 namespace {
 constexpr uint32_t kHalStartRetryMaxCount = 5;
 constexpr uint32_t kHalStartRetryIntervalInMs = 2;
@@ -86,7 +88,8 @@
 }  // namespace
 
 sp<IWifi> getWifi() {
-    sp<IWifi> wifi = ::testing::VtsHalHidlTargetTestBase::getService<IWifi>();
+    sp<IWifi> wifi = ::testing::VtsHalHidlTargetTestBase::getService<IWifi>(
+        gEnv->getServiceName<IWifi>());
     return wifi;
 }
 
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
index c4a19dd..2b1c8ec 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
@@ -26,6 +26,7 @@
 
 #include <getopt.h>
 
+#include <VtsHalHidlTargetTestEnvBase.h>
 // Helper functions to obtain references to the various HIDL interface objects.
 // Note: We only have a single instance of each of these objects currently.
 // These helper functions should be modified to return vectors if we support
@@ -47,9 +48,9 @@
 // Used to trigger IWifi.stop() at the end of every test.
 void stopWifi();
 
-class WifiHidlEnvironment : public ::testing::Environment {
+class WifiHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    protected:
-    virtual void SetUp() override {
+    virtual void HidlSetUp() override {
         stopWifi();
         sleep(5);
     }
diff --git a/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
index 9b92b57..a0f97f8 100644
--- a/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
+++ b/wifi/1.1/vts/functional/VtsHalWifiV1_1TargetTest.cpp
@@ -15,17 +15,32 @@
  */
 
 #include <android-base/logging.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/1.1/IWifi.h>
 
 #include "wifi_hidl_test_utils.h"
 
-WifiHidlEnvironment* gEnv;
+class WifiHidlEnvironment_1_1 : public WifiHidlEnvironment {
+   public:
+    // get the test environment singleton
+    static WifiHidlEnvironment_1_1* Instance() {
+        static WifiHidlEnvironment_1_1* instance = new WifiHidlEnvironment_1_1;
+        return instance;
+    }
+
+    virtual void registerTestServices() override {
+        registerTestService<android::hardware::wifi::V1_1::IWifi>();
+    }
+
+   private:
+    WifiHidlEnvironment_1_1() {}
+};
+
+WifiHidlEnvironment* gEnv = WifiHidlEnvironment_1_1::Instance();
 
 int main(int argc, char** argv) {
-    gEnv = new WifiHidlEnvironment();
     ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
     int status = gEnv->initFromOptions(argc, argv);
     if (status == 0) {
         int status = RUN_ALL_TESTS();
diff --git a/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp b/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
index 64e6fbe..0303b20 100644
--- a/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
+++ b/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
@@ -15,20 +15,34 @@
  */
 
 #include <android-base/logging.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
 
 #include "hostapd_hidl_test_utils.h"
 
-class HostapdHidlEnvironment : public ::testing::Environment {
+class WifiHostapdHidlEnvironment_1_0 : public WifiHostapdHidlEnvironment {
    public:
-    virtual void SetUp() override { stopHostapd(); }
-    virtual void TearDown() override { startHostapdAndWaitForHidlService(); }
+    // get the test environment singleton
+    static WifiHostapdHidlEnvironment_1_0* Instance() {
+        static WifiHostapdHidlEnvironment_1_0* instance =
+            new WifiHostapdHidlEnvironment_1_0;
+        return instance;
+    }
+
+    virtual void registerTestServices() override {
+        registerTestService<::android::hardware::wifi::V1_0::IWifi>();
+        registerTestService<android::hardware::wifi::hostapd::V1_0::IHostapd>();
+    }
+
+   private:
+    WifiHostapdHidlEnvironment_1_0() {}
 };
 
+WifiHostapdHidlEnvironment* gEnv = WifiHostapdHidlEnvironment_1_0::Instance();
+
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(new HostapdHidlEnvironment);
+    ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     LOG(INFO) << "Test result = " << status;
     return status;
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
index 0915150..e5ba8ef 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
@@ -42,9 +42,9 @@
 using ::android::hidl::manager::V1_0::IServiceNotification;
 using ::android::wifi_system::HostapdManager;
 
-namespace {
-const char kHostapdServiceName[] = "default";
+extern WifiHostapdHidlEnvironment* gEnv;
 
+namespace {
 // Helper function to initialize the driver and firmware to AP mode
 // using the vendor HAL HIDL interface.
 void initilializeDriverAndFirmware() {
@@ -120,16 +120,17 @@
 
     android::sp<ServiceNotificationListener> notification_listener =
         new ServiceNotificationListener();
+    string service_name = gEnv->getServiceName<IHostapd>();
     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
-        kHostapdServiceName));
+        service_name));
 
     HostapdManager hostapd_manager;
     ASSERT_TRUE(hostapd_manager.StartHostapd());
 
-    ASSERT_TRUE(
-        notification_listener->waitForHidlService(200, kHostapdServiceName));
+    ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
 }
 
 sp<IHostapd> getHostapd() {
-    return ::testing::VtsHalHidlTargetTestBase::getService<IHostapd>();
+    return ::testing::VtsHalHidlTargetTestBase::getService<IHostapd>(
+        gEnv->getServiceName<IHostapd>());
 }
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
index 74ed284..1b92477 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
@@ -19,6 +19,8 @@
 
 #include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
 
+#include <VtsHalHidlTargetTestEnvBase.h>
+
 // Used to stop the android wifi framework before every test.
 void stopWifiFramework();
 void startWifiFramework();
@@ -33,4 +35,13 @@
 // multiple instances.
 android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd> getHostapd();
 
+class WifiHostapdHidlEnvironment
+    : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    virtual void HidlSetUp() override { stopHostapd(); }
+    virtual void HidlTearDown() override {
+        startHostapdAndWaitForHidlService();
+    }
+};
+
 #endif /* HOSTAPD_HIDL_TEST_UTILS_H */
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index 90c36dd..dbe4e74 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -23,6 +23,7 @@
 
 #include <VtsHalHidlTargetCallbackBase.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
 #include <vector>
 
@@ -68,12 +69,33 @@
     OffloadStatus error_code_;
 };
 
+// Test environment for Weaver HIDL HAL.
+class WifiOffloadHidlEnvironment
+    : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    // get the test environment singleton
+    static WifiOffloadHidlEnvironment* Instance() {
+        static WifiOffloadHidlEnvironment* instance =
+            new WifiOffloadHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override {
+        registerTestService<IOffload>();
+    }
+
+   private:
+    WifiOffloadHidlEnvironment() {}
+};
+
 // The main test class for WifiOffload HIDL HAL.
 class WifiOffloadHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    public:
     virtual void SetUp() override {
         wifi_offload_ =
-            ::testing::VtsHalHidlTargetTestBase::getService<IOffload>();
+            ::testing::VtsHalHidlTargetTestBase::getService<IOffload>(
+                WifiOffloadHidlEnvironment::Instance()
+                    ->getServiceName<IOffload>());
         ASSERT_NE(wifi_offload_, nullptr);
 
         wifi_offload_cb_ = new OffloadCallback();
@@ -209,17 +231,10 @@
     ASSERT_EQ(true, res.no_timeout);
 }
 
-// A class for test environment setup
-class WifiOffloadHalHidlEnvironment : public ::testing::Environment {
-   public:
-    virtual void SetUp() {}
-    virtual void TearDown() {}
-};
-
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(new WifiOffloadHalHidlEnvironment);
+    ::testing::AddGlobalTestEnvironment(WifiOffloadHidlEnvironment::Instance());
     ::testing::InitGoogleTest(&argc, argv);
-
+    WifiOffloadHidlEnvironment::Instance()->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     LOG(INFO) << "Test result = " << status;
 
diff --git a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
index 7fa20c9..adf2a85 100644
--- a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
+++ b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp
@@ -16,21 +16,34 @@
 
 #include <android-base/logging.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-
 #include "supplicant_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
 
-class SupplicantHidlEnvironment : public ::testing::Environment {
+class WifiSupplicantHidlEnvironment_1_0 : public WifiSupplicantHidlEnvironment {
    public:
-    virtual void SetUp() override {
-        stopSupplicant();
+    // get the test environment singleton
+    static WifiSupplicantHidlEnvironment_1_0* Instance() {
+        static WifiSupplicantHidlEnvironment_1_0* instance =
+            new WifiSupplicantHidlEnvironment_1_0;
+        return instance;
     }
-    virtual void TearDown() override { startSupplicantAndWaitForHidlService(); }
+    virtual void registerTestServices() override {
+        registerTestService<::android::hardware::wifi::V1_0::IWifi>();
+        registerTestService<
+            ::android::hardware::wifi::supplicant::V1_0::ISupplicant>();
+    }
+
+   private:
+    WifiSupplicantHidlEnvironment_1_0() {}
 };
 
+WifiSupplicantHidlEnvironment* gEnv =
+    WifiSupplicantHidlEnvironment_1_0::Instance();
+
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(new SupplicantHidlEnvironment);
+    ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     LOG(INFO) << "Test result = " << status;
     return status;
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 3b75508..6dd64ec 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <android-base/logging.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
 
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <android/hidl/manager/1.0/IServiceNotification.h>
@@ -49,8 +49,9 @@
 using ::android::wifi_system::InterfaceTool;
 using ::android::wifi_system::SupplicantManager;
 
+extern WifiSupplicantHidlEnvironment* gEnv;
+
 namespace {
-const char kSupplicantServiceName[] = "default";
 
 // Helper function to initialize the driver and firmware to STA mode
 // using the vendor HAL HIDL interface.
@@ -153,19 +154,20 @@
 
     android::sp<ServiceNotificationListener> notification_listener =
         new ServiceNotificationListener();
+    string service_name = gEnv->getServiceName<ISupplicant>();
     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
-        kSupplicantServiceName));
+        service_name));
 
     SupplicantManager supplicant_manager;
     ASSERT_TRUE(supplicant_manager.StartSupplicant());
     ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
 
-    ASSERT_TRUE(
-        notification_listener->waitForHidlService(200, kSupplicantServiceName));
+    ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
 }
 
 sp<ISupplicant> getSupplicant() {
-    return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>();
+    return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
+        gEnv->getServiceName<ISupplicant>());
 }
 
 sp<ISupplicantStaIface> getSupplicantStaIface() {
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 38143e4..4426ab6 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -22,6 +22,8 @@
 #include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
 #include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>
 
+#include <VtsHalHidlTargetTestEnvBase.h>
+
 // Used to stop the android wifi framework before every test.
 void stopWifiFramework();
 void startWifiFramework();
@@ -45,4 +47,13 @@
 
 bool turnOnExcessiveLogging();
 
+class WifiSupplicantHidlEnvironment
+    : public ::testing::VtsHalHidlTargetTestEnvBase {
+   public:
+    virtual void HidlSetUp() override { stopSupplicant(); }
+    virtual void HidlTearDown() override {
+        startSupplicantAndWaitForHidlService();
+    }
+};
+
 #endif /* SUPPLICANT_HIDL_TEST_UTILS_H */
diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp
index 9375cf5..188dba3 100644
--- a/wifi/supplicant/1.1/vts/functional/Android.bp
+++ b/wifi/supplicant/1.1/vts/functional/Android.bp
@@ -48,6 +48,7 @@
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
         "libcrypto",
         "libgmock",
         "libwifi-system",
diff --git a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp
index b5e369a..3d24fc3 100644
--- a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp
+++ b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp
@@ -15,20 +15,37 @@
  */
 
 #include <android-base/logging.h>
-
-#include <VtsHalHidlTargetTestBase.h>
+#include <android/hardware/wifi/1.1/IWifi.h>
+#include <android/hardware/wifi/supplicant/1.1/ISupplicant.h>
 
 #include "supplicant_hidl_test_utils.h"
+#include "wifi_hidl_test_utils.h"
 
-class SupplicantHidlEnvironment : public ::testing::Environment {
+class WifiSupplicantHidlEnvironment_1_1 : public WifiSupplicantHidlEnvironment {
    public:
-    virtual void SetUp() override { stopSupplicant(); }
-    virtual void TearDown() override { startSupplicantAndWaitForHidlService(); }
+    // get the test environment singleton
+    static WifiSupplicantHidlEnvironment_1_1* Instance() {
+        static WifiSupplicantHidlEnvironment_1_1* instance =
+            new WifiSupplicantHidlEnvironment_1_1;
+        return instance;
+    }
+    virtual void registerTestServices() override {
+        registerTestService<::android::hardware::wifi::V1_1::IWifi>();
+        registerTestService<
+            ::android::hardware::wifi::supplicant::V1_1::ISupplicant>();
+    }
+
+   private:
+    WifiSupplicantHidlEnvironment_1_1() {}
 };
 
+WifiSupplicantHidlEnvironment* gEnv =
+    WifiSupplicantHidlEnvironment_1_1::Instance();
+
 int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(new SupplicantHidlEnvironment);
+    ::testing::AddGlobalTestEnvironment(gEnv);
     ::testing::InitGoogleTest(&argc, argv);
+    gEnv->init(&argc, argv);
     int status = RUN_ALL_TESTS();
     LOG(INFO) << "Test result = " << status;
     return status;