Merge "Restore "Add "Unlocked device required" parameter to keys""
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/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/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..ca74ae1 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -655,6 +655,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);
@@ -2748,42 +2755,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 +2805,7 @@
                 });
         ASSERT_TRUE(ret.isOk());
 
-        sessionParams.unlock(sessionParamsBuffer);
+        free_camera_metadata(staticMetaBuffer);
         ret = session->close();
         ASSERT_TRUE(ret.isOk());
     }
@@ -3350,6 +3338,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 +3347,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 +3357,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 +3423,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 +3487,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,6 +3540,8 @@
         ASSERT_TRUE(returnStatus.isOk());
         ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat);
 
+        defaultPreviewSettings.unlock(settingsBuffer);
+        filteredSettings.unlock(filteredSettingsBuffer);
         ret = session3_4->close();
         ASSERT_TRUE(ret.isOk());
     }
@@ -3901,6 +3947,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/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/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/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.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/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..8b38f42 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.
@@ -397,3 +414,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;