Merge "[RenderEngine] Fix test build for RenderEngine refactor"
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..98e125b
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "hidl_implementation_test"
+    }
+  ]
+}
+
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 2703b2b..15be3bf 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -24,7 +24,7 @@
     //        flushCommand makes sure all local command are sent, thus should reduce
     //        the latency between local and remote destruction.
     IPCThreadState::self()->flushCommands();
-    usleep(100);
+    usleep(100 * 1000);
 }
 
 TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index fb96323..0778720 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -699,13 +699,27 @@
 
     Return<Result> closeStream() {
         open = false;
-        return stream->close();
+        auto res = stream->close();
+        stream.clear();
+        waitForStreamDestruction();
+        return res;
+    }
+
+    void waitForStreamDestruction() {
+        // FIXME: there is no way to know when the remote IStream is being destroyed
+        //        Binder does not support testing if an object is alive, thus
+        //        wait for 100ms to let the binder destruction propagates and
+        //        the remote device has the time to be destroyed.
+        //        flushCommand makes sure all local command are sent, thus should reduce
+        //        the latency between local and remote destruction.
+        IPCThreadState::self()->flushCommands();
+        usleep(100 * 1000);
     }
 
    private:
     void TearDown() override {
         if (open) {
-            ASSERT_OK(stream->close());
+            ASSERT_OK(closeStream());
         }
         AudioConfigPrimaryTest::TearDown();
     }
@@ -1003,8 +1017,14 @@
                ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
 
 TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
-TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", ASSERT_OK(closeStream());
-               ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
+// clang-format off
+TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
+        auto streamCopy = stream;
+        ASSERT_OK(closeStream());
+        ASSERT_RESULT(Result::INVALID_STATE, streamCopy->close());
+        streamCopy.clear();
+        waitForStreamDestruction())
+// clang-format on
 
 static void testCreateTooBigMmapBuffer(IStream* stream) {
     MmapBufferInfo info;
diff --git a/current.txt b/current.txt
index 87649d2..9ab1967 100644
--- a/current.txt
+++ b/current.txt
@@ -589,12 +589,12 @@
 74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
 34515afa2bb792d3c6d8495a5f5d907d179c8507ca5e55c10050d02ae1d516ef android.hardware.neuralnetworks@1.3::IDevice
 b74fe72cfe438f50e772e6a307657ff449d5bde83c15dd1f140ff2edbe73499c android.hardware.neuralnetworks@1.3::types
-04395b26be33db17747c3d3b0e8066d323f891ff4f9f3b3ddb490b2f3f844a18 android.hardware.wifi@1.4::IWifi
-270f0eb670dfd9bc5cd718e09711f2534fa8425f54d06c1a46523ca156b509e2 android.hardware.wifi.supplicant@1.3::ISupplicant
-dd4b7cfbb6e1c6ff011c33920762ad89dd02240c63a4d3a3d5037f154eae3e3b android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
-619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
-6fe09b18e913608579638594788198ec45bb2369e567d7df661db46c4f0e5f08 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
-91931b05bd70ea6bdffbe075086183f803379571788564e28854207620eb75cf android.hardware.wifi.supplicant@1.3::types
 544049dcda3f943ad67d83d5277f06681a3782982a9af5a78b5d4e8d295d061a android.hardware.vibrator@1.4::IVibrator
 5e1c12efbbba89c9143d10b1b90eceff8bc79aa079f5106215b528e104fef101 android.hardware.vibrator@1.4::IVibratorCallback
 033eae03c09ebc75e82db37bc39995dfaa9086745577b44d9e14e9ccb48bd8cc android.hardware.vibrator@1.4::types
+3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi
+a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
+0a7ff83fd0326b82232e1609da98f34960be11335df72fc407ad238d7bd0e081 android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
+619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
+c9273429fcf98d797d3bb07fdba6f1be95bf960f9255cde169fd1ca4db85f856 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
+b0f8c9cd61a45a8c1b4a8e40913ecaea0921011cbe2305a6fa5a2feaa0d36c30 android.hardware.wifi.supplicant@1.3::types
diff --git a/dumpstate/1.0/vts/functional/Android.bp b/dumpstate/1.0/vts/functional/Android.bp
index fc64d05..3bac281 100644
--- a/dumpstate/1.0/vts/functional/Android.bp
+++ b/dumpstate/1.0/vts/functional/Android.bp
@@ -18,5 +18,5 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalDumpstateV1_0TargetTest.cpp"],
     static_libs: ["android.hardware.dumpstate@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
index 57ebf2a..96b13c5 100644
--- a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
+++ b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
@@ -21,32 +21,19 @@
 
 #include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
 #include <cutils/native_handle.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <log/log.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
 using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
 using ::android::hardware::Return;
 using ::android::sp;
 
-// Test environment for Dumpstate HIDL HAL.
-class DumpstateHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static DumpstateHidlEnvironment* Instance() {
-        static DumpstateHidlEnvironment* instance = new DumpstateHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IDumpstateDevice>(); }
-};
-
-class DumpstateHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   public:
+class DumpstateHidlTest : public ::testing::TestWithParam<std::string> {
+  public:
     virtual void SetUp() override {
-        dumpstate = ::testing::VtsHalHidlTargetTestBase::getService<IDumpstateDevice>(
-            DumpstateHidlEnvironment::Instance()->getServiceName<IDumpstateDevice>());
+        dumpstate = IDumpstateDevice::getService(GetParam());
         ASSERT_NE(dumpstate, nullptr) << "Could not get HIDL instance";
     }
 
@@ -54,14 +41,14 @@
 };
 
 // Negative test: make sure dumpstateBoard() doesn't crash when passed a null pointer.
-TEST_F(DumpstateHidlTest, TestNullHandle) {
+TEST_P(DumpstateHidlTest, TestNullHandle) {
     Return<void> status = dumpstate->dumpstateBoard(nullptr);
 
     ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
 }
 
 // Negative test: make sure dumpstateBoard() ignores a handle with no FD.
-TEST_F(DumpstateHidlTest, TestHandleWithNoFd) {
+TEST_P(DumpstateHidlTest, TestHandleWithNoFd) {
     native_handle_t* handle = native_handle_create(0, 0);
     ASSERT_NE(handle, nullptr) << "Could not create native_handle";
 
@@ -74,7 +61,7 @@
 }
 
 // Positive test: make sure dumpstateBoard() writes something to the FD.
-TEST_F(DumpstateHidlTest, TestOk) {
+TEST_P(DumpstateHidlTest, TestOk) {
     // Index 0 corresponds to the read end of the pipe; 1 to the write end.
     int fds[2];
     ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
@@ -94,7 +81,7 @@
 }
 
 // Positive test: make sure dumpstateBoard() doesn't crash with two FDs.
-TEST_F(DumpstateHidlTest, TestHandleWithTwoFds) {
+TEST_P(DumpstateHidlTest, TestHandleWithTwoFds) {
     int fds1[2];
     int fds2[2];
     ASSERT_EQ(0, pipe2(fds1, O_NONBLOCK)) << errno;
@@ -111,11 +98,7 @@
     native_handle_close(handle);
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(DumpstateHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    DumpstateHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    ALOGI("Test result = %d", status);
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, DumpstateHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IDumpstateDevice::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/health/2.0/default/Android.bp b/health/2.0/default/Android.bp
index 1c455d3..3c5877e 100644
--- a/health/2.0/default/Android.bp
+++ b/health/2.0/default/Android.bp
@@ -31,7 +31,11 @@
     vendor_available: true,
     srcs: [
         "Health.cpp",
-        "healthd_common.cpp",
+        "healthd_common_adapter.cpp",
+    ],
+
+    whole_static_libs: [
+        "libhealthloop",
     ],
 
     export_include_dirs: ["include"],
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index a2b81d1..c0c5a40 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -148,7 +148,14 @@
 
     // Retrieve all information and call healthd_mode_ops->battery_update, which calls
     // notifyListeners.
-    bool chargerOnline = battery_monitor_->update();
+    battery_monitor_->updateValues();
+    struct BatteryProperties props = getBatteryProperties(battery_monitor_.get());
+    bool log = healthd_board_battery_update(&props);
+    if (log) {
+        battery_monitor_->logValues();
+    }
+    healthd_mode_ops->battery_update(&props);
+    bool chargerOnline = battery_monitor_->isChargerOnline();
 
     // adjust uevent / wakealarm periods
     healthd_battery_update_internal(chargerOnline);
diff --git a/health/2.0/default/healthd_common.cpp b/health/2.0/default/healthd_common.cpp
deleted file mode 100644
index b5fdc8e..0000000
--- a/health/2.0/default/healthd_common.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2013 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 "android.hardware.health@2.0-impl"
-#define KLOG_LEVEL 6
-
-#include <healthd/BatteryMonitor.h>
-#include <healthd/healthd.h>
-
-#include <batteryservice/BatteryService.h>
-#include <cutils/klog.h>
-#include <cutils/uevent.h>
-#include <errno.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#include <unistd.h>
-#include <utils/Errors.h>
-
-#include <health2/Health.h>
-
-using namespace android;
-
-// Periodic chores fast interval in seconds
-#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
-// Periodic chores fast interval in seconds
-#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
-
-static struct healthd_config healthd_config = {
-    .periodic_chores_interval_fast = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST,
-    .periodic_chores_interval_slow = DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW,
-    .batteryStatusPath = String8(String8::kEmptyString),
-    .batteryHealthPath = String8(String8::kEmptyString),
-    .batteryPresentPath = String8(String8::kEmptyString),
-    .batteryCapacityPath = String8(String8::kEmptyString),
-    .batteryVoltagePath = String8(String8::kEmptyString),
-    .batteryTemperaturePath = String8(String8::kEmptyString),
-    .batteryTechnologyPath = String8(String8::kEmptyString),
-    .batteryCurrentNowPath = String8(String8::kEmptyString),
-    .batteryCurrentAvgPath = String8(String8::kEmptyString),
-    .batteryChargeCounterPath = String8(String8::kEmptyString),
-    .batteryFullChargePath = String8(String8::kEmptyString),
-    .batteryCycleCountPath = String8(String8::kEmptyString),
-    .energyCounter = NULL,
-    .boot_min_cap = 0,
-    .screen_on = NULL,
-};
-
-static int eventct;
-static int epollfd;
-
-#define POWER_SUPPLY_SUBSYSTEM "power_supply"
-
-static int uevent_fd;
-static int wakealarm_fd;
-
-// -1 for no epoll timeout
-static int awake_poll_interval = -1;
-
-static int wakealarm_wake_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST;
-
-using ::android::hardware::health::V2_0::implementation::Health;
-
-struct healthd_mode_ops* healthd_mode_ops = nullptr;
-
-int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
-    struct epoll_event ev;
-
-    ev.events = EPOLLIN;
-
-    if (wakeup == EVENT_WAKEUP_FD) ev.events |= EPOLLWAKEUP;
-
-    ev.data.ptr = (void*)handler;
-    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
-        KLOG_ERROR(LOG_TAG, "epoll_ctl failed; errno=%d\n", errno);
-        return -1;
-    }
-
-    eventct++;
-    return 0;
-}
-
-static void wakealarm_set_interval(int interval) {
-    struct itimerspec itval;
-
-    if (wakealarm_fd == -1) return;
-
-    wakealarm_wake_interval = interval;
-
-    if (interval == -1) interval = 0;
-
-    itval.it_interval.tv_sec = interval;
-    itval.it_interval.tv_nsec = 0;
-    itval.it_value.tv_sec = interval;
-    itval.it_value.tv_nsec = 0;
-
-    if (timerfd_settime(wakealarm_fd, 0, &itval, NULL) == -1)
-        KLOG_ERROR(LOG_TAG, "wakealarm_set_interval: timerfd_settime failed\n");
-}
-
-void healthd_battery_update_internal(bool charger_online) {
-    // Fast wake interval when on charger (watch for overheat);
-    // slow wake interval when on battery (watch for drained battery).
-
-    int new_wake_interval = charger_online ? healthd_config.periodic_chores_interval_fast
-                                           : healthd_config.periodic_chores_interval_slow;
-
-    if (new_wake_interval != wakealarm_wake_interval) wakealarm_set_interval(new_wake_interval);
-
-    // During awake periods poll at fast rate.  If wake alarm is set at fast
-    // rate then just use the alarm; if wake alarm is set at slow rate then
-    // poll at fast rate while awake and let alarm wake up at slow rate when
-    // asleep.
-
-    if (healthd_config.periodic_chores_interval_fast == -1)
-        awake_poll_interval = -1;
-    else
-        awake_poll_interval = new_wake_interval == healthd_config.periodic_chores_interval_fast
-                                  ? -1
-                                  : healthd_config.periodic_chores_interval_fast * 1000;
-}
-
-static void healthd_battery_update(void) {
-    Health::getImplementation()->update();
-}
-
-static void periodic_chores() {
-    healthd_battery_update();
-}
-
-#define UEVENT_MSG_LEN 2048
-static void uevent_event(uint32_t /*epevents*/) {
-    char msg[UEVENT_MSG_LEN + 2];
-    char* cp;
-    int n;
-
-    n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN);
-    if (n <= 0) return;
-    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
-        return;
-
-    msg[n] = '\0';
-    msg[n + 1] = '\0';
-    cp = msg;
-
-    while (*cp) {
-        if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) {
-            healthd_battery_update();
-            break;
-        }
-
-        /* advance to after the next \0 */
-        while (*cp++)
-            ;
-    }
-}
-
-static void uevent_init(void) {
-    uevent_fd = uevent_open_socket(64 * 1024, true);
-
-    if (uevent_fd < 0) {
-        KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
-        return;
-    }
-
-    fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
-    if (healthd_register_event(uevent_fd, uevent_event, EVENT_WAKEUP_FD))
-        KLOG_ERROR(LOG_TAG, "register for uevent events failed\n");
-}
-
-static void wakealarm_event(uint32_t /*epevents*/) {
-    unsigned long long wakeups;
-
-    if (read(wakealarm_fd, &wakeups, sizeof(wakeups)) == -1) {
-        KLOG_ERROR(LOG_TAG, "wakealarm_event: read wakealarm fd failed\n");
-        return;
-    }
-
-    periodic_chores();
-}
-
-static void wakealarm_init(void) {
-    wakealarm_fd = timerfd_create(CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK);
-    if (wakealarm_fd == -1) {
-        KLOG_ERROR(LOG_TAG, "wakealarm_init: timerfd_create failed\n");
-        return;
-    }
-
-    if (healthd_register_event(wakealarm_fd, wakealarm_event, EVENT_WAKEUP_FD))
-        KLOG_ERROR(LOG_TAG, "Registration of wakealarm event failed\n");
-
-    wakealarm_set_interval(healthd_config.periodic_chores_interval_fast);
-}
-
-static void healthd_mainloop(void) {
-    int nevents = 0;
-    while (1) {
-        struct epoll_event events[eventct];
-        int timeout = awake_poll_interval;
-        int mode_timeout;
-
-        /* Don't wait for first timer timeout to run periodic chores */
-        if (!nevents) periodic_chores();
-
-        healthd_mode_ops->heartbeat();
-
-        mode_timeout = healthd_mode_ops->preparetowait();
-        if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout)) timeout = mode_timeout;
-        nevents = epoll_wait(epollfd, events, eventct, timeout);
-        if (nevents == -1) {
-            if (errno == EINTR) continue;
-            KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n");
-            break;
-        }
-
-        for (int n = 0; n < nevents; ++n) {
-            if (events[n].data.ptr) (*(void (*)(int))events[n].data.ptr)(events[n].events);
-        }
-    }
-
-    return;
-}
-
-static int healthd_init() {
-    epollfd = epoll_create1(EPOLL_CLOEXEC);
-    if (epollfd == -1) {
-        KLOG_ERROR(LOG_TAG, "epoll_create1 failed; errno=%d\n", errno);
-        return -1;
-    }
-
-    healthd_mode_ops->init(&healthd_config);
-    wakealarm_init();
-    uevent_init();
-
-    return 0;
-}
-
-int healthd_main() {
-    int ret;
-
-    klog_set_level(KLOG_LEVEL);
-
-    if (!healthd_mode_ops) {
-        KLOG_ERROR("healthd ops not set, exiting\n");
-        exit(1);
-    }
-
-    ret = healthd_init();
-    if (ret) {
-        KLOG_ERROR("Initialization failed, exiting\n");
-        exit(2);
-    }
-
-    healthd_mainloop();
-    KLOG_ERROR("Main loop terminated, exiting\n");
-    return 3;
-}
diff --git a/health/2.0/default/healthd_common_adapter.cpp b/health/2.0/default/healthd_common_adapter.cpp
new file mode 100644
index 0000000..8fc689d
--- /dev/null
+++ b/health/2.0/default/healthd_common_adapter.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// Support legacy functions in healthd/healthd.h using healthd_mode_ops.
+// New code should use HealthLoop directly instead.
+
+#include <memory>
+
+#include <cutils/klog.h>
+#include <health/HealthLoop.h>
+#include <health2/Health.h>
+#include <healthd/healthd.h>
+
+using android::hardware::health::HealthLoop;
+using android::hardware::health::V2_0::implementation::Health;
+
+struct healthd_mode_ops* healthd_mode_ops = nullptr;
+
+// Adapter of HealthLoop to use legacy healthd_mode_ops.
+class HealthLoopAdapter : public HealthLoop {
+   public:
+    // Expose internal functions, assuming clients calls them in the same thread
+    // where StartLoop is called.
+    int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
+        return HealthLoop::RegisterEvent(fd, func, wakeup);
+    }
+    void AdjustWakealarmPeriods(bool charger_online) {
+        return HealthLoop::AdjustWakealarmPeriods(charger_online);
+    }
+   protected:
+    void Init(healthd_config* config) override { healthd_mode_ops->init(config); }
+    void Heartbeat() override { healthd_mode_ops->heartbeat(); }
+    int PrepareToWait() override { return healthd_mode_ops->preparetowait(); }
+    void ScheduleBatteryUpdate() override { Health::getImplementation()->update(); }
+};
+static std::unique_ptr<HealthLoopAdapter> health_loop;
+
+int healthd_register_event(int fd, void (*handler)(uint32_t), EventWakeup wakeup) {
+    auto wrapped_handler = [handler](auto*, uint32_t epevents) { handler(epevents); };
+    return health_loop->RegisterEvent(fd, wrapped_handler, wakeup);
+}
+
+void healthd_battery_update_internal(bool charger_online) {
+    health_loop->AdjustWakealarmPeriods(charger_online);
+}
+
+int healthd_main() {
+    if (!healthd_mode_ops) {
+        KLOG_ERROR("healthd ops not set, exiting\n");
+        exit(1);
+    }
+
+    health_loop = std::make_unique<HealthLoopAdapter>();
+
+    int ret = health_loop->StartLoop();
+
+    // Should not reach here. The following will exit().
+    health_loop.reset();
+
+    return ret;
+}
diff --git a/health/utils/libhealthloop/Android.bp b/health/utils/libhealthloop/Android.bp
new file mode 100644
index 0000000..de0f24f
--- /dev/null
+++ b/health/utils/libhealthloop/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2019 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_library_static {
+    name: "libhealthloop",
+    vendor_available: true,
+    recovery_available: true,
+    srcs: [
+        "HealthLoop.cpp",
+        "utils.cpp",
+    ],
+    shared_libs: [
+        "libcutils",
+        "libbase",
+    ],
+    header_libs: [
+        "libbatteryservice_headers",
+        "libhealthd_headers",
+        "libutils_headers",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+}
diff --git a/health/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
new file mode 100644
index 0000000..3f4b5bc
--- /dev/null
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2013 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 "HealthLoop"
+#define KLOG_LEVEL 6
+
+#include <health/HealthLoop.h>
+
+#include <errno.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <batteryservice/BatteryService.h>
+#include <cutils/klog.h>
+#include <cutils/uevent.h>
+#include <healthd/healthd.h>
+#include <utils/Errors.h>
+
+#include <health/utils.h>
+
+using namespace android;
+using namespace std::chrono_literals;
+
+#define POWER_SUPPLY_SUBSYSTEM "power_supply"
+
+namespace android {
+namespace hardware {
+namespace health {
+
+HealthLoop::HealthLoop() {
+    InitHealthdConfig(&healthd_config_);
+    awake_poll_interval_ = -1;
+    wakealarm_wake_interval_ = healthd_config_.periodic_chores_interval_fast;
+}
+
+HealthLoop::~HealthLoop() {
+    LOG(FATAL) << "HealthLoop cannot be destroyed";
+}
+
+int HealthLoop::RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
+    CHECK(!reject_event_register_);
+
+    auto* event_handler =
+            event_handlers_
+                    .emplace_back(std::make_unique<EventHandler>(EventHandler{this, fd, func}))
+                    .get();
+
+    struct epoll_event ev;
+
+    ev.events = EPOLLIN;
+
+    if (wakeup == EVENT_WAKEUP_FD) ev.events |= EPOLLWAKEUP;
+
+    ev.data.ptr = reinterpret_cast<void*>(event_handler);
+
+    if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
+        KLOG_ERROR(LOG_TAG, "epoll_ctl failed; errno=%d\n", errno);
+        return -1;
+    }
+
+    return 0;
+}
+
+void HealthLoop::WakeAlarmSetInterval(int interval) {
+    struct itimerspec itval;
+
+    if (wakealarm_fd_ == -1) return;
+
+    wakealarm_wake_interval_ = interval;
+
+    if (interval == -1) interval = 0;
+
+    itval.it_interval.tv_sec = interval;
+    itval.it_interval.tv_nsec = 0;
+    itval.it_value.tv_sec = interval;
+    itval.it_value.tv_nsec = 0;
+
+    if (timerfd_settime(wakealarm_fd_, 0, &itval, NULL) == -1)
+        KLOG_ERROR(LOG_TAG, "wakealarm_set_interval: timerfd_settime failed\n");
+}
+
+void HealthLoop::AdjustWakealarmPeriods(bool charger_online) {
+    // Fast wake interval when on charger (watch for overheat);
+    // slow wake interval when on battery (watch for drained battery).
+
+    int new_wake_interval = charger_online ? healthd_config_.periodic_chores_interval_fast
+                                           : healthd_config_.periodic_chores_interval_slow;
+
+    if (new_wake_interval != wakealarm_wake_interval_) WakeAlarmSetInterval(new_wake_interval);
+
+    // During awake periods poll at fast rate.  If wake alarm is set at fast
+    // rate then just use the alarm; if wake alarm is set at slow rate then
+    // poll at fast rate while awake and let alarm wake up at slow rate when
+    // asleep.
+
+    if (healthd_config_.periodic_chores_interval_fast == -1)
+        awake_poll_interval_ = -1;
+    else
+        awake_poll_interval_ = new_wake_interval == healthd_config_.periodic_chores_interval_fast
+                                       ? -1
+                                       : healthd_config_.periodic_chores_interval_fast * 1000;
+}
+
+void HealthLoop::PeriodicChores() {
+    ScheduleBatteryUpdate();
+}
+
+// TODO(b/140330870): Use BPF instead.
+#define UEVENT_MSG_LEN 2048
+void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
+    // No need to lock because uevent_fd_ is guaranteed to be initialized.
+
+    char msg[UEVENT_MSG_LEN + 2];
+    char* cp;
+    int n;
+
+    n = uevent_kernel_multicast_recv(uevent_fd_, msg, UEVENT_MSG_LEN);
+    if (n <= 0) return;
+    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
+        return;
+
+    msg[n] = '\0';
+    msg[n + 1] = '\0';
+    cp = msg;
+
+    while (*cp) {
+        if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) {
+            ScheduleBatteryUpdate();
+            break;
+        }
+
+        /* advance to after the next \0 */
+        while (*cp++)
+            ;
+    }
+}
+
+void HealthLoop::UeventInit(void) {
+    uevent_fd_.reset(uevent_open_socket(64 * 1024, true));
+
+    if (uevent_fd_ < 0) {
+        KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
+        return;
+    }
+
+    fcntl(uevent_fd_, F_SETFL, O_NONBLOCK);
+    if (RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD))
+        KLOG_ERROR(LOG_TAG, "register for uevent events failed\n");
+}
+
+void HealthLoop::WakeAlarmEvent(uint32_t /*epevents*/) {
+    // No need to lock because wakealarm_fd_ is guaranteed to be initialized.
+
+    unsigned long long wakeups;
+
+    if (read(wakealarm_fd_, &wakeups, sizeof(wakeups)) == -1) {
+        KLOG_ERROR(LOG_TAG, "wakealarm_event: read wakealarm fd failed\n");
+        return;
+    }
+
+    PeriodicChores();
+}
+
+void HealthLoop::WakeAlarmInit(void) {
+    wakealarm_fd_.reset(timerfd_create(CLOCK_BOOTTIME_ALARM, TFD_NONBLOCK));
+    if (wakealarm_fd_ == -1) {
+        KLOG_ERROR(LOG_TAG, "wakealarm_init: timerfd_create failed\n");
+        return;
+    }
+
+    if (RegisterEvent(wakealarm_fd_, &HealthLoop::WakeAlarmEvent, EVENT_WAKEUP_FD))
+        KLOG_ERROR(LOG_TAG, "Registration of wakealarm event failed\n");
+
+    WakeAlarmSetInterval(healthd_config_.periodic_chores_interval_fast);
+}
+
+void HealthLoop::MainLoop(void) {
+    int nevents = 0;
+    while (1) {
+        reject_event_register_ = true;
+        size_t eventct = event_handlers_.size();
+        struct epoll_event events[eventct];
+        int timeout = awake_poll_interval_;
+
+        int mode_timeout;
+
+        /* Don't wait for first timer timeout to run periodic chores */
+        if (!nevents) PeriodicChores();
+
+        Heartbeat();
+
+        mode_timeout = PrepareToWait();
+        if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout)) timeout = mode_timeout;
+        nevents = epoll_wait(epollfd_, events, eventct, timeout);
+        if (nevents == -1) {
+            if (errno == EINTR) continue;
+            KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n");
+            break;
+        }
+
+        for (int n = 0; n < nevents; ++n) {
+            if (events[n].data.ptr) {
+                auto* event_handler = reinterpret_cast<EventHandler*>(events[n].data.ptr);
+                event_handler->func(event_handler->object, events[n].events);
+            }
+        }
+    }
+
+    return;
+}
+
+int HealthLoop::InitInternal() {
+    epollfd_.reset(epoll_create1(EPOLL_CLOEXEC));
+    if (epollfd_ == -1) {
+        KLOG_ERROR(LOG_TAG, "epoll_create1 failed; errno=%d\n", errno);
+        return -1;
+    }
+
+    // Call subclass's init for any additional init steps.
+    // Note that healthd_config_ is initialized before wakealarm_fd_; see
+    // AdjustUeventWakealarmPeriods().
+    Init(&healthd_config_);
+
+    WakeAlarmInit();
+    UeventInit();
+
+    return 0;
+}
+
+int HealthLoop::StartLoop() {
+    int ret;
+
+    klog_set_level(KLOG_LEVEL);
+
+    ret = InitInternal();
+    if (ret) {
+        KLOG_ERROR(LOG_TAG, "Initialization failed, exiting\n");
+        return 2;
+    }
+
+    MainLoop();
+    KLOG_ERROR(LOG_TAG, "Main loop terminated, exiting\n");
+    return 3;
+}
+
+}  // namespace health
+}  // namespace hardware
+}  // namespace android
diff --git a/health/utils/libhealthloop/include/health/HealthLoop.h b/health/utils/libhealthloop/include/health/HealthLoop.h
new file mode 100644
index 0000000..693e6cb
--- /dev/null
+++ b/health/utils/libhealthloop/include/health/HealthLoop.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#include <android-base/unique_fd.h>
+#include <healthd/healthd.h>
+
+namespace android {
+namespace hardware {
+namespace health {
+
+class HealthLoop {
+  public:
+    HealthLoop();
+
+    // Client is responsible for holding this forever. Process will exit
+    // when this is destroyed.
+    virtual ~HealthLoop();
+
+    // Initialize and start the main loop. This function does not exit unless
+    // the process is interrupted.
+    // Once the loop is started, event handlers are no longer allowed to be
+    // registered.
+    int StartLoop();
+
+  protected:
+    // healthd_mode_ops overrides. Note that healthd_mode_ops->battery_update
+    // is missing because it is only used by BatteryMonitor.
+    // Init is called right after epollfd_ is initialized (so RegisterEvent
+    // is allowed) but before other things are initialized (so SetChargerOnline
+    // is not allowed.)
+    virtual void Init(healthd_config* config) = 0;
+    virtual void Heartbeat() = 0;
+    virtual int PrepareToWait() = 0;
+
+    // Note that this is NOT healthd_mode_ops->battery_update(BatteryProperties*),
+    // which is called by BatteryMonitor after values are fetched. This is the
+    // implementation of healthd_battery_update(), which calls
+    // the correct IHealth::update(),
+    // which calls BatteryMonitor::update(), which calls
+    // healthd_mode_ops->battery_update(BatteryProperties*).
+    virtual void ScheduleBatteryUpdate() = 0;
+
+    // Register an epoll event. When there is an event, |func| will be
+    // called with |this| as the first argument and |epevents| as the second.
+    // This may be called in a different thread from where StartLoop is called
+    // (for obvious reasons; StartLoop never ends).
+    // Once the loop is started, event handlers are no longer allowed to be
+    // registered.
+    using BoundFunction = std::function<void(HealthLoop*, uint32_t /* epevents */)>;
+    int RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup);
+
+    // Helper for implementing ScheduleBatteryUpdate(). An implementation of
+    // ScheduleBatteryUpdate should get charger_online from BatteryMonitor::update(),
+    // then reset wake alarm interval by calling AdjustWakealarmPeriods.
+    void AdjustWakealarmPeriods(bool charger_online);
+
+  private:
+    struct EventHandler {
+        HealthLoop* object = nullptr;
+        int fd;
+        BoundFunction func;
+    };
+
+    int InitInternal();
+    void MainLoop();
+    void WakeAlarmInit();
+    void WakeAlarmEvent(uint32_t);
+    void UeventInit();
+    void UeventEvent(uint32_t);
+    void WakeAlarmSetInterval(int interval);
+    void PeriodicChores();
+
+    // These are fixed after InitInternal() is called.
+    struct healthd_config healthd_config_;
+    android::base::unique_fd wakealarm_fd_;
+    android::base::unique_fd uevent_fd_;
+
+    android::base::unique_fd epollfd_;
+    std::vector<std::unique_ptr<EventHandler>> event_handlers_;
+    int awake_poll_interval_;  // -1 for no epoll timeout
+    int wakealarm_wake_interval_;
+
+    // If set to true, future RegisterEvent() will be rejected. This is to ensure all
+    // events are registered before StartLoop().
+    bool reject_event_register_ = false;
+};
+
+}  // namespace health
+}  // namespace hardware
+}  // namespace android
diff --git a/health/utils/libhealthloop/include/health/utils.h b/health/utils/libhealthloop/include/health/utils.h
new file mode 100644
index 0000000..e46771c
--- /dev/null
+++ b/health/utils/libhealthloop/include/health/utils.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <healthd/healthd.h>
+
+namespace android {
+namespace hardware {
+namespace health {
+
+void InitHealthdConfig(struct healthd_config* healthd_config);
+
+}  // namespace health
+}  // namespace hardware
+}  // namespace android
diff --git a/health/utils/libhealthloop/utils.cpp b/health/utils/libhealthloop/utils.cpp
new file mode 100644
index 0000000..b0d153f
--- /dev/null
+++ b/health/utils/libhealthloop/utils.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <health/utils.h>
+namespace android {
+namespace hardware {
+namespace health {
+
+// Periodic chores fast interval in seconds
+#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
+// Periodic chores fast interval in seconds
+#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
+
+void InitHealthdConfig(struct healthd_config* healthd_config) {
+    *healthd_config = {
+            .periodic_chores_interval_fast = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST,
+            .periodic_chores_interval_slow = DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW,
+            .batteryStatusPath = String8(String8::kEmptyString),
+            .batteryHealthPath = String8(String8::kEmptyString),
+            .batteryPresentPath = String8(String8::kEmptyString),
+            .batteryCapacityPath = String8(String8::kEmptyString),
+            .batteryVoltagePath = String8(String8::kEmptyString),
+            .batteryTemperaturePath = String8(String8::kEmptyString),
+            .batteryTechnologyPath = String8(String8::kEmptyString),
+            .batteryCurrentNowPath = String8(String8::kEmptyString),
+            .batteryCurrentAvgPath = String8(String8::kEmptyString),
+            .batteryChargeCounterPath = String8(String8::kEmptyString),
+            .batteryFullChargePath = String8(String8::kEmptyString),
+            .batteryCycleCountPath = String8(String8::kEmptyString),
+            .energyCounter = NULL,
+            .boot_min_cap = 0,
+            .screen_on = NULL,
+    };
+}
+
+}  // namespace health
+}  // namespace hardware
+}  // namespace android
diff --git a/nfc/1.0/vts/functional/Android.bp b/nfc/1.0/vts/functional/Android.bp
index c2e365e..40b82bb 100644
--- a/nfc/1.0/vts/functional/Android.bp
+++ b/nfc/1.0/vts/functional/Android.bp
@@ -21,5 +21,5 @@
     static_libs: [
         "android.hardware.nfc@1.0",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/nfc/1.0/vts/functional/AndroidTest.xml b/nfc/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..364672b
--- /dev/null
+++ b/nfc/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs VtsHalNfcV1_0TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalNfcV1_0TargetTest->/data/local/tmp/VtsHalNfcV1_0TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalNfcV1_0TargetTest" />
+        <option name="native-test-timeout" value="180000"/>
+    </test>
+</configuration>
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index e17c961..1feae9d 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -20,11 +20,12 @@
 #include <android/hardware/nfc/1.0/INfc.h>
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
 #include <android/hardware/nfc/1.0/types.h>
+#include <gtest/gtest.h>
 #include <hardware/nfc.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::hardware::nfc::V1_0::INfc;
 using ::android::hardware::nfc::V1_0::INfcClientCallback;
@@ -94,26 +95,11 @@
     };
 };
 
-// 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 {
+class NfcHidlTest : public ::testing::TestWithParam<std::string> {
  public:
   virtual void SetUp() override {
-    nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>(
-        NfcHidlEnvironment::Instance()->getServiceName<INfc>());
+    nfc_ = INfc::getService(GetParam());
     ASSERT_NE(nfc_, nullptr);
 
     nfc_cb_ = new NfcClientCallback();
@@ -186,7 +172,7 @@
  * Since open and close calls are a part of SetUp() and TearDown(),
  * the function definition is intentionally kept empty
  */
-TEST_F(NfcHidlTest, OpenAndClose) {}
+TEST_P(NfcHidlTest, OpenAndClose) {}
 
 /*
  * WriteCoreReset:
@@ -194,7 +180,7 @@
  * Waits for CORE_RESET_RSP
  * Checks the status, version number and configuration status
  */
-TEST_F(NfcHidlTest, WriteCoreReset) {
+TEST_P(NfcHidlTest, WriteCoreReset) {
   std::vector<uint8_t> cmd = CORE_RESET_CMD;
   NfcData data = cmd;
   EXPECT_EQ(data.size(), nfc_->write(data));
@@ -229,7 +215,7 @@
  * Waits for CORE_RESET_RSP
  * Checks the status, version number and configuration status
  */
-TEST_F(NfcHidlTest, WriteCoreResetConfigReset) {
+TEST_P(NfcHidlTest, WriteCoreResetConfigReset) {
   std::vector<uint8_t> cmd = CORE_RESET_CMD_CONFIG_RESET;
   NfcData data = cmd;
   EXPECT_EQ(data.size(), nfc_->write(data));
@@ -264,7 +250,7 @@
  * Waits for response
  * Checks SYNTAX_ERROR status
  */
-TEST_F(NfcHidlTest, WriteInvalidCommand) {
+TEST_P(NfcHidlTest, WriteInvalidCommand) {
   // Send an Error Command
   std::vector<uint8_t> cmd = INVALID_COMMAND;
   NfcData data = cmd;
@@ -285,7 +271,7 @@
  * Send CORE_CONN_CREATE_CMD for loop-back mode
  * Check the response
  */
-TEST_F(NfcHidlTest, WriteInvalidAndThenValidCommand) {
+TEST_P(NfcHidlTest, WriteInvalidAndThenValidCommand) {
     std::vector<uint8_t> cmd = CORE_RESET_CMD;
     NfcData data = cmd;
     EXPECT_EQ(data.size(), nfc_->write(data));
@@ -349,7 +335,7 @@
  * Checks the data received
  * Repeat to send total of 1Mb data
  */
-TEST_F(NfcHidlTest, Bandwidth) {
+TEST_P(NfcHidlTest, Bandwidth) {
     std::vector<uint8_t> cmd = CORE_RESET_CMD;
     NfcData data = cmd;
     EXPECT_EQ(data.size(), nfc_->write(data));
@@ -437,7 +423,7 @@
  * Waits for NfcEvent.OPEN_CPLT
  * Checks status
  */
-TEST_F(NfcHidlTest, PowerCycle) {
+TEST_P(NfcHidlTest, PowerCycle) {
   EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
   // Wait for NfcEvent.OPEN_CPLT
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -451,7 +437,7 @@
  * Calls powerCycle() after close()
  * Checks status
  */
-TEST_F(NfcHidlTest, PowerCycleAfterClose) {
+TEST_P(NfcHidlTest, PowerCycleAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -474,7 +460,7 @@
  * Calls coreInitialized() with different data
  * Waits for NfcEvent.POST_INIT_CPLT
  */
-TEST_F(NfcHidlTest, CoreInitialized) {
+TEST_P(NfcHidlTest, CoreInitialized) {
   NfcData data;
   data.resize(1);
   // These parameters might lead to device specific proprietary behavior
@@ -501,7 +487,7 @@
  * Calls controlGranted()
  * Checks the return value
  */
-TEST_F(NfcHidlTest, ControlGranted) {
+TEST_P(NfcHidlTest, ControlGranted) {
   EXPECT_EQ(NfcStatus::OK, nfc_->controlGranted());
 }
 
@@ -510,7 +496,7 @@
  * Call controlGranted() after close
  * Checks the return value
  */
-TEST_F(NfcHidlTest, ControlGrantedAfterClose) {
+TEST_P(NfcHidlTest, ControlGrantedAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -532,7 +518,7 @@
  * Calls prediscover()
  * Checks the return value
  */
-TEST_F(NfcHidlTest, PreDiscover) {
+TEST_P(NfcHidlTest, PreDiscover) {
   EXPECT_EQ(NfcStatus::OK, nfc_->prediscover());
 }
 
@@ -541,7 +527,7 @@
  * Call prediscover() after close
  * Checks the return value
  */
-TEST_F(NfcHidlTest, PreDiscoverAfterClose) {
+TEST_P(NfcHidlTest, PreDiscoverAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -564,7 +550,7 @@
  * Calls close() multiple times
  * Checks status
  */
-TEST_F(NfcHidlTest, CloseAfterClose) {
+TEST_P(NfcHidlTest, CloseAfterClose) {
   EXPECT_EQ(NfcStatus::OK, nfc_->close());
   // Wait for CLOSE_CPLT event
   auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -587,15 +573,18 @@
  * Calls open() multiple times
  * Checks status
  */
-TEST_F(NfcHidlTest, OpenAfterOpen) {
+TEST_P(NfcHidlTest, OpenAfterOpen) {
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
   EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
 }
 
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, NfcHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(INfc::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 int main(int argc, char** argv) {
-  ::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/Android.bp b/nfc/1.1/vts/functional/Android.bp
index 6698c5a..8da0ce3 100644
--- a/nfc/1.1/vts/functional/Android.bp
+++ b/nfc/1.1/vts/functional/Android.bp
@@ -22,5 +22,5 @@
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp b/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
index 0b7c88b..13537e4 100644
--- a/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
+++ b/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
@@ -21,11 +21,12 @@
 #include <android/hardware/nfc/1.1/INfc.h>
 #include <android/hardware/nfc/1.1/INfcClientCallback.h>
 #include <android/hardware/nfc/1.1/types.h>
+#include <gtest/gtest.h>
 #include <hardware/nfc.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::hardware::nfc::V1_1::INfc;
 using ::android::hardware::nfc::V1_1::INfcClientCallback;
@@ -83,25 +84,11 @@
     };
 };
 
-// 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 {
+class NfcHidlTest : public ::testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>();
+        nfc_ = INfc::getService(GetParam());
         ASSERT_NE(nfc_, nullptr);
 
         nfc_cb_ = new NfcClientCallback();
@@ -151,7 +138,7 @@
  * calls factoryReset()
  * checks status
  */
-TEST_F(NfcHidlTest, FactoryReset) {
+TEST_P(NfcHidlTest, FactoryReset) {
     nfc_->factoryReset();
 
     EXPECT_EQ(NfcStatus::OK, nfc_->close());
@@ -174,7 +161,7 @@
  * Makes an open call, waits for NfcEvent.OPEN_CPLT
  * Immediately calls closeforPowerOffCase() and waits for NfcEvent.CLOSE_CPLT
  */
-TEST_F(NfcHidlTest, OpenAndCloseForPowerOff) {
+TEST_P(NfcHidlTest, OpenAndCloseForPowerOff) {
     EXPECT_EQ(NfcStatus::OK, nfc_->closeForPowerOffCase());
     // Wait for CLOSE_CPLT event
     auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -195,7 +182,7 @@
  * Calls closeForPowerOffCase()
  * Calls close() - checks failed status
  */
-TEST_F(NfcHidlTest, CloseForPowerCaseOffAfterClose) {
+TEST_P(NfcHidlTest, CloseForPowerCaseOffAfterClose) {
     EXPECT_EQ(NfcStatus::OK, nfc_->closeForPowerOffCase());
     // Wait for CLOSE_CPLT event
     auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -218,16 +205,19 @@
  * Calls getConfig()
  * checks if fields in NfcConfig are populated correctly
  */
-TEST_F(NfcHidlTest, GetConfig) {
+TEST_P(NfcHidlTest, GetConfig) {
     nfc_->getConfig([](NfcConfig config) {
         EXPECT_GE(config.maxIsoDepTransceiveLength, MIN_ISO_DEP_TRANSCEIVE_LENGTH);
     });
 }
 
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, NfcHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(INfc::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 int main(int argc, char** argv) {
-    ::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.2/vts/functional/Android.bp b/nfc/1.2/vts/functional/Android.bp
index 13b254c..7b50a36 100644
--- a/nfc/1.2/vts/functional/Android.bp
+++ b/nfc/1.2/vts/functional/Android.bp
@@ -23,4 +23,5 @@
         "android.hardware.nfc@1.1",
         "android.hardware.nfc@1.2",
     ],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp b/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp
index 54d3127..3ec088d 100644
--- a/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp
+++ b/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp
@@ -20,11 +20,12 @@
 #include <android/hardware/nfc/1.1/INfcClientCallback.h>
 #include <android/hardware/nfc/1.2/INfc.h>
 #include <android/hardware/nfc/1.2/types.h>
+#include <gtest/gtest.h>
 #include <hardware/nfc.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 
 using ::android::sp;
 using ::android::hardware::hidl_vec;
@@ -83,26 +84,11 @@
     };
 };
 
-// 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 {
+class NfcHidlTest : public ::testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>();
+        nfc_ = INfc::getService(GetParam());
         ASSERT_NE(nfc_, nullptr);
 
         nfc_cb_ = new NfcClientCallback();
@@ -152,7 +138,7 @@
  * Calls getConfig()
  * checks if fields in NfcConfig are populated correctly
  */
-TEST_F(NfcHidlTest, GetExtendedConfig) {
+TEST_P(NfcHidlTest, GetExtendedConfig) {
     nfc_->getConfig_1_2([](NfcConfig config) {
         for (uint8_t uicc : config.offHostRouteUicc) {
             EXPECT_GE(uicc, MIN_OFFHOST_ROUTE_ID);
@@ -169,10 +155,13 @@
     });
 }
 
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, NfcHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(INfc::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 int main(int argc, char** argv) {
-    ::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/power/1.0/vts/functional/Android.bp b/power/1.0/vts/functional/Android.bp
index a716f02..5d5676d 100644
--- a/power/1.0/vts/functional/Android.bp
+++ b/power/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalPowerV1_0TargetTest.cpp"],
     static_libs: ["android.hardware.power@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
index 999b2b4..ba08ee7 100644
--- a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
+++ b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
@@ -21,9 +21,9 @@
 
 #include <android-base/unique_fd.h>
 #include <android/hardware/power/1.0/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include <fcntl.h>
 #include <algorithm>
@@ -45,23 +45,10 @@
 #define AVAILABLE_GOVERNORS_PATH \
   "/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
 
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static PowerHidlEnvironment* Instance() {
-        static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
  public:
   virtual void SetUp() override {
-      power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
-          PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+      power = IPower::getService(GetParam());
       ASSERT_NE(power, nullptr);
   }
 
@@ -71,7 +58,7 @@
 };
 
 // Sanity check Power::setInteractive.
-TEST_F(PowerHidlTest, SetInteractive) {
+TEST_P(PowerHidlTest, SetInteractive) {
   Return<void> ret;
 
   ret = power->setInteractive(true);
@@ -83,7 +70,7 @@
 
 // Test Power::setInteractive and Power::powerHint(Launch)
 // with each available CPU governor, if available
-TEST_F(PowerHidlTest, TryDifferentGovernors) {
+TEST_P(PowerHidlTest, TryDifferentGovernors) {
   Return<void> ret;
 
   unique_fd fd1(open(CPU_GOVERNOR_PATH, O_RDWR));
@@ -125,7 +112,7 @@
 }
 
 // Sanity check Power::powerHint on good and bad inputs.
-TEST_F(PowerHidlTest, PowerHint) {
+TEST_P(PowerHidlTest, PowerHint) {
   PowerHint badHint = static_cast<PowerHint>(0xA);
   auto hints = {PowerHint::VSYNC,         PowerHint::INTERACTION,
                 PowerHint::VIDEO_ENCODE,  PowerHint::VIDEO_DECODE,
@@ -163,7 +150,7 @@
 }
 
 // Sanity check Power::setFeature() on good and bad inputs.
-TEST_F(PowerHidlTest, SetFeature) {
+TEST_P(PowerHidlTest, SetFeature) {
   Return<void> ret;
   ret = power->setFeature(Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE, true);
   ASSERT_TRUE(ret.isOk());
@@ -178,7 +165,7 @@
 }
 
 // Sanity check Power::getPlatformLowPowerStats().
-TEST_F(PowerHidlTest, GetPlatformLowPowerStats) {
+TEST_P(PowerHidlTest, GetPlatformLowPowerStats) {
   hidl_vec<PowerStatePlatformSleepState> vec;
   Status s;
   auto cb = [&vec, &s](hidl_vec<PowerStatePlatformSleepState> states,
@@ -191,11 +178,7 @@
   ASSERT_TRUE(s == Status::SUCCESS || s == Status::FILESYSTEM_ERROR);
 }
 
-int main(int argc, char **argv) {
-    ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    PowerHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, PowerHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/power/1.1/vts/functional/Android.bp b/power/1.1/vts/functional/Android.bp
index de75984..d9a32df 100644
--- a/power/1.1/vts/functional/Android.bp
+++ b/power/1.1/vts/functional/Android.bp
@@ -22,5 +22,5 @@
         "android.hardware.power@1.0",
         "android.hardware.power@1.1",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp b/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
index 4427b15..e9a722c 100644
--- a/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
+++ b/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
@@ -17,9 +17,9 @@
 #define LOG_TAG "power_hidl_hal_test"
 #include <android-base/logging.h>
 #include <android/hardware/power/1.1/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using ::android::hardware::power::V1_1::IPower;
 using ::android::hardware::power::V1_1::PowerStateSubsystem;
@@ -29,23 +29,10 @@
 using ::android::hardware::Return;
 using ::android::sp;
 
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static PowerHidlEnvironment* Instance() {
-        static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
  public:
   virtual void SetUp() override {
-      power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
-          PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+      power = IPower::getService(GetParam());
       ASSERT_NE(power, nullptr);
   }
 
@@ -55,7 +42,7 @@
 };
 
 // Sanity check Power::getSubsystemLowPowerStats().
-TEST_F(PowerHidlTest, GetSubsystemLowPowerStats) {
+TEST_P(PowerHidlTest, GetSubsystemLowPowerStats) {
   hidl_vec<PowerStateSubsystem> vec;
   Status s;
   auto cb = [&vec, &s](hidl_vec<PowerStateSubsystem> subsystems,
@@ -70,7 +57,7 @@
 }
 
 // Sanity check Power::powerHintAsync on good and bad inputs.
-TEST_F(PowerHidlTest, PowerHintAsync) {
+TEST_P(PowerHidlTest, PowerHintAsync) {
     PowerHint badHint = static_cast<PowerHint>(0xA);
     auto hints = {PowerHint::VSYNC,        PowerHint::INTERACTION, PowerHint::VIDEO_ENCODE,
                   PowerHint::VIDEO_DECODE, PowerHint::LOW_POWER,   PowerHint::SUSTAINED_PERFORMANCE,
@@ -104,11 +91,7 @@
     } while (std::next_permutation(hints2.begin(), hints2.end(), compareHints));
 }
 
-int main(int argc, char **argv) {
-    ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    PowerHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, PowerHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/power/1.2/vts/functional/Android.bp b/power/1.2/vts/functional/Android.bp
index f424bfa..5385faa 100644
--- a/power/1.2/vts/functional/Android.bp
+++ b/power/1.2/vts/functional/Android.bp
@@ -23,5 +23,5 @@
         "android.hardware.power@1.1",
         "android.hardware.power@1.2",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp b/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
index 5e92997..a5ecf5d 100644
--- a/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
+++ b/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
@@ -17,9 +17,9 @@
 #define LOG_TAG "power_hidl_hal_test"
 #include <android-base/logging.h>
 #include <android/hardware/power/1.2/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using ::android::sp;
 using ::android::hardware::hidl_vec;
@@ -27,23 +27,10 @@
 using ::android::hardware::power::V1_2::IPower;
 using ::android::hardware::power::V1_2::PowerHint;
 
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static PowerHidlEnvironment* Instance() {
-        static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
-            PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+        power = IPower::getService(GetParam());
         ASSERT_NE(power, nullptr);
     }
 
@@ -51,7 +38,7 @@
 };
 
 // Sanity check Power::PowerHintAsync_1_2 on good and bad inputs.
-TEST_F(PowerHidlTest, PowerHintAsync_1_2) {
+TEST_P(PowerHidlTest, PowerHintAsync_1_2) {
     std::vector<PowerHint> hints;
     for (uint32_t i = static_cast<uint32_t>(PowerHint::VSYNC);
          i <= static_cast<uint32_t>(PowerHint::CAMERA_SHOT); ++i) {
@@ -89,11 +76,8 @@
     } while (std::next_permutation(hints2.begin(), hints2.end(), compareHints));
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    PowerHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, PowerHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
diff --git a/power/1.3/vts/functional/Android.bp b/power/1.3/vts/functional/Android.bp
index 06f6e7a..77e8619 100644
--- a/power/1.3/vts/functional/Android.bp
+++ b/power/1.3/vts/functional/Android.bp
@@ -24,5 +24,5 @@
         "android.hardware.power@1.2",
         "android.hardware.power@1.3",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp b/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp
index af1a1d8..3cf2adc 100644
--- a/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp
+++ b/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp
@@ -17,9 +17,9 @@
 #define LOG_TAG "power_hidl_hal_test"
 #include <android-base/logging.h>
 #include <android/hardware/power/1.3/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using ::android::sp;
 using ::android::hardware::hidl_vec;
@@ -27,38 +27,21 @@
 using ::android::hardware::power::V1_3::IPower;
 using ::android::hardware::power::V1_3::PowerHint;
 
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static PowerHidlEnvironment* Instance() {
-        static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
-            PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+        power = IPower::getService(GetParam());
         ASSERT_NE(power, nullptr);
     }
 
     sp<IPower> power;
 };
 
-TEST_F(PowerHidlTest, PowerHintAsync_1_3) {
+TEST_P(PowerHidlTest, PowerHintAsync_1_3) {
     ASSERT_TRUE(power->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING, 0).isOk());
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    PowerHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, PowerHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/power/stats/1.0/vts/functional/Android.bp b/power/stats/1.0/vts/functional/Android.bp
index f564cbe..ab47061 100644
--- a/power/stats/1.0/vts/functional/Android.bp
+++ b/power/stats/1.0/vts/functional/Android.bp
@@ -33,4 +33,5 @@
         "libfmq",
         "libutils",
     ],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp b/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp
index 835a47b..3359669 100644
--- a/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp
+++ b/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp
@@ -16,13 +16,15 @@
 
 #define LOG_TAG "android.power.stats.vts"
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/power/stats/1.0/IPowerStats.h>
 #include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
 #include <hidl/MQDescriptor.h>
+#include <hidl/ServiceManagement.h>
 #include <inttypes.h>
+
 #include <algorithm>
 #include <random>
 #include <thread>
@@ -49,23 +51,11 @@
 }  // namespace
 
 typedef hardware::MessageQueue<EnergyData, kSynchronizedReadWrite> MessageQueueSync;
-// Test environment for Power HIDL HAL.
-class PowerStatsHidlEnv : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static PowerStatsHidlEnv* Instance() {
-        static PowerStatsHidlEnv* instance = new PowerStatsHidlEnv;
-        return instance;
-    }
 
-    virtual void registerTestServices() override { registerTestService<IPowerStats>(); }
-};
-
-class PowerStatsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerStatsHidlTest : public ::testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        service_ = ::testing::VtsHalHidlTargetTestBase::getService<IPowerStats>(
-            PowerStatsHidlEnv::Instance()->getServiceName<IPowerStats>());
+        service_ = IPowerStats::getService(GetParam());
         ASSERT_NE(service_, nullptr);
     }
 
@@ -157,7 +147,7 @@
 }
 
 // Each PowerEntity must have a valid name
-TEST_F(PowerStatsHidlTest, ValidatePowerEntityNames) {
+TEST_P(PowerStatsHidlTest, ValidatePowerEntityNames) {
     hidl_vec<PowerEntityInfo> infos;
     getInfos(infos);
     for (auto info : infos) {
@@ -166,18 +156,18 @@
 }
 
 // Each PowerEntity must have a unique ID
-TEST_F(PowerStatsHidlTest, ValidatePowerEntityIds) {
+TEST_P(PowerStatsHidlTest, ValidatePowerEntityIds) {
     hidl_vec<PowerEntityInfo> infos;
     getInfos(infos);
 
-    set<uint32_t> ids;
+    std::set<uint32_t> ids;
     for (auto info : infos) {
         ASSERT_TRUE(ids.insert(info.powerEntityId).second);
     }
 }
 
 // Each PowerEntityStateSpace must have an associated PowerEntityInfo
-TEST_F(PowerStatsHidlTest, ValidateStateInfoAssociation) {
+TEST_P(PowerStatsHidlTest, ValidateStateInfoAssociation) {
     hidl_vec<PowerEntityInfo> infos;
     getInfos(infos);
 
@@ -195,7 +185,7 @@
 }
 
 // Each state must have a valid name
-TEST_F(PowerStatsHidlTest, ValidateStateNames) {
+TEST_P(PowerStatsHidlTest, ValidateStateNames) {
     hidl_vec<PowerEntityStateSpace> stateSpaces;
     getStateSpaces(stateSpaces);
 
@@ -207,12 +197,12 @@
 }
 
 // Each state must have an ID that is unique to the PowerEntityStateSpace
-TEST_F(PowerStatsHidlTest, ValidateStateUniqueIds) {
+TEST_P(PowerStatsHidlTest, ValidateStateUniqueIds) {
     hidl_vec<PowerEntityStateSpace> stateSpaces;
     getStateSpaces(stateSpaces);
 
     for (auto stateSpace : stateSpaces) {
-        set<uint32_t> stateIds;
+        std::set<uint32_t> stateIds;
         for (auto state : stateSpace.states) {
             ASSERT_TRUE(stateIds.insert(state.powerEntityStateId).second);
         }
@@ -221,7 +211,7 @@
 
 // getPowerEntityStateInfo must support passing in requested IDs
 // Results must contain state space information for all requested IDs
-TEST_F(PowerStatsHidlTest, ValidateStateInfoAssociationSelect) {
+TEST_P(PowerStatsHidlTest, ValidateStateInfoAssociationSelect) {
     std::vector<uint32_t> randomIds;
     getRandomIds(randomIds);
 
@@ -244,7 +234,7 @@
 }
 
 // Requested state space info must match initially obtained stateinfos
-TEST_F(PowerStatsHidlTest, ValidateStateInfoSelect) {
+TEST_P(PowerStatsHidlTest, ValidateStateInfoSelect) {
     hidl_vec<PowerEntityStateSpace> stateSpaces;
     getStateSpaces(stateSpaces);
     if (stateSpaces.size() == 0) {
@@ -279,7 +269,7 @@
 
 // stateResidencyResults must contain results for every PowerEntityStateSpace
 // returned by getPowerEntityStateInfo
-TEST_F(PowerStatsHidlTest, ValidateResidencyResultsAssociation) {
+TEST_P(PowerStatsHidlTest, ValidateResidencyResultsAssociation) {
     hidl_vec<PowerEntityStateSpace> stateSpaces;
     getStateSpaces(stateSpaces);
 
@@ -311,7 +301,7 @@
 // getPowerEntityStateResidencyData must support passing in requested IDs
 // stateResidencyResults must contain results for each PowerEntityStateSpace
 // returned by getPowerEntityStateInfo
-TEST_F(PowerStatsHidlTest, ValidateResidencyResultsAssociationSelect) {
+TEST_P(PowerStatsHidlTest, ValidateResidencyResultsAssociationSelect) {
     std::vector<uint32_t> randomIds;
     getRandomIds(randomIds);
     if (randomIds.empty()) {
@@ -346,7 +336,7 @@
     }
 }
 
-TEST_F(PowerStatsHidlTest, ValidateRailInfo) {
+TEST_P(PowerStatsHidlTest, ValidateRailInfo) {
     hidl_vec<RailInfo> rails[2];
     Status s;
     auto cb = [&rails, &s](hidl_vec<RailInfo> rail_subsys, Status status) {
@@ -359,7 +349,7 @@
         /* Rails size should be non-zero on SUCCESS*/
         ASSERT_NE(rails[0].size(), 0);
         /* check if indices returned are unique*/
-        set<uint32_t> ids;
+        std::set<uint32_t> ids;
         for (auto rail : rails[0]) {
             ASSERT_TRUE(ids.insert(rail.index).second);
         }
@@ -402,7 +392,7 @@
     }
 }
 
-TEST_F(PowerStatsHidlTest, ValidateAllPowerData) {
+TEST_P(PowerStatsHidlTest, ValidateAllPowerData) {
     hidl_vec<EnergyData> measurements[2];
     Status s;
     auto cb = [&measurements, &s](hidl_vec<EnergyData> measure, Status status) {
@@ -451,7 +441,7 @@
     }
 }
 
-TEST_F(PowerStatsHidlTest, ValidateFilteredPowerData) {
+TEST_P(PowerStatsHidlTest, ValidateFilteredPowerData) {
     hidl_vec<RailInfo> rails;
     hidl_vec<EnergyData> measurements;
     hidl_vec<uint32_t> indices;
@@ -559,23 +549,19 @@
     }
 }
 
-TEST_F(PowerStatsHidlTest, StreamEnergyData) {
+TEST_P(PowerStatsHidlTest, StreamEnergyData) {
     std::time_t seed = std::time(nullptr);
     std::srand(seed);
     std::thread thread1 = std::thread(readEnergy, service_, std::rand() % 5000);
     thread1.join();
 }
 
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, PowerStatsHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPowerStats::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 }  // namespace vts
 }  // namespace stats
 }  // namespace power
 }  // namespace android
-
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(android::power::stats::vts::PowerStatsHidlEnv::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    android::power::stats::vts::PowerStatsHidlEnv::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
diff --git a/vibrator/1.0/vts/functional/Android.bp b/vibrator/1.0/vts/functional/Android.bp
index 391d3d4..10ec2cb 100644
--- a/vibrator/1.0/vts/functional/Android.bp
+++ b/vibrator/1.0/vts/functional/Android.bp
@@ -19,6 +19,6 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalVibratorV1_0TargetTest.cpp"],
     static_libs: ["android.hardware.vibrator@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
 
diff --git a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
index 6f8aa02..2aee338 100644
--- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
+++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
@@ -21,8 +21,9 @@
 #include <android/hardware/vibrator/1.0/types.h>
 #include <unistd.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using ::android::sp;
 using ::android::hardware::hidl_enum_range;
@@ -35,27 +36,11 @@
 
 #define EXPECT_OK(ret) EXPECT_TRUE((ret).isOk())
 
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
-  // get the test environment singleton
-  static VibratorHidlEnvironment* Instance() {
-      static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
-      return instance;
-  }
-
-  virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
- private:
-  VibratorHidlEnvironment() {}
-};
-
 // The main test class for VIBRATOR HIDL HAL.
-class VibratorHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest : public ::testing::TestWithParam<std::string> {
  public:
   virtual void SetUp() override {
-    vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
-        VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+    vibrator = IVibrator::getService(GetParam());
     ASSERT_NE(vibrator, nullptr);
   }
 
@@ -79,13 +64,13 @@
             << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
 }
 
-TEST_F(VibratorHidlTest, OnThenOffBeforeTimeout) {
+TEST_P(VibratorHidlTest, OnThenOffBeforeTimeout) {
   EXPECT_EQ(Status::OK, vibrator->on(2000));
   sleep(1);
   EXPECT_EQ(Status::OK, vibrator->off());
 }
 
-TEST_F(VibratorHidlTest, PerformEffect) {
+TEST_P(VibratorHidlTest, PerformEffect) {
   vibrator->perform(Effect::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
   vibrator->perform(Effect::DOUBLE_CLICK, EffectStrength::LIGHT, validatePerformEffect);
 }
@@ -93,7 +78,7 @@
 /*
  * Test to make sure effect values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest, PerformEffect_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadEffects_AboveValidRange) {
     Effect effect = *std::prev(hidl_enum_range<Effect>().end());
     Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
     EXPECT_OK(vibrator->perform(badEffect, EffectStrength::LIGHT, validatePerformEffectBadInput));
@@ -102,7 +87,7 @@
 /*
  * Test to make sure effect values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest, PerformEffect_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadEffects_BelowValidRange) {
     Effect effect = *hidl_enum_range<Effect>().begin();
     Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
     EXPECT_OK(vibrator->perform(badEffect, EffectStrength::LIGHT, validatePerformEffectBadInput));
@@ -111,7 +96,7 @@
 /*
  * Test to make sure strength values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest, PerformEffect_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadStrength_AboveValidRange) {
     EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
     EXPECT_OK(vibrator->perform(Effect::CLICK, badStrength, validatePerformEffectBadInput));
@@ -120,13 +105,13 @@
 /*
  * Test to make sure strength values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest, PerformEffect_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadStrength_BelowValidRange) {
     EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
     EXPECT_OK(vibrator->perform(Effect::CLICK, badStrength, validatePerformEffectBadInput));
 }
 
-TEST_F(VibratorHidlTest, ChangeVibrationalAmplitude) {
+TEST_P(VibratorHidlTest, ChangeVibrationalAmplitude) {
   if (vibrator->supportsAmplitudeControl()) {
     EXPECT_EQ(Status::OK, vibrator->setAmplitude(1));
     EXPECT_EQ(Status::OK, vibrator->on(2000));
@@ -137,23 +122,19 @@
   }
 }
 
-TEST_F(VibratorHidlTest, AmplitudeOutsideRangeFails) {
+TEST_P(VibratorHidlTest, AmplitudeOutsideRangeFails) {
   if (vibrator->supportsAmplitudeControl()) {
     EXPECT_EQ(Status::BAD_VALUE, vibrator->setAmplitude(0));
   }
 }
 
-TEST_F(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
+TEST_P(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
   if (!vibrator->supportsAmplitudeControl()) {
     EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setAmplitude(1));
   }
 }
 
-int main(int argc, char **argv) {
-  ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
-  ::testing::InitGoogleTest(&argc, argv);
-  VibratorHidlEnvironment::Instance()->init(&argc, argv);
-  int status = RUN_ALL_TESTS();
-  LOG(INFO) << "Test result = " << status;
-  return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, VibratorHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.1/vts/functional/Android.bp b/vibrator/1.1/vts/functional/Android.bp
index c65ff41..4cde350 100644
--- a/vibrator/1.1/vts/functional/Android.bp
+++ b/vibrator/1.1/vts/functional/Android.bp
@@ -22,6 +22,6 @@
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
 
diff --git a/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp b/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
index 3c3ebf2..da94308 100644
--- a/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
+++ b/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
@@ -16,11 +16,12 @@
 
 #define LOG_TAG "vibrator_hidl_hal_test"
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/vibrator/1.1/IVibrator.h>
 #include <android/hardware/vibrator/1.1/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <unistd.h>
 
 using ::android::sp;
@@ -34,27 +35,11 @@
 
 #define EXPECT_OK(ret) EXPECT_TRUE((ret).isOk())
 
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static VibratorHidlEnvironment* Instance() {
-        static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
-   private:
-    VibratorHidlEnvironment() {}
-};
-
 // The main test class for VIBRATOR HIDL HAL 1.1.
-class VibratorHidlTest_1_1 : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest_1_1 : public ::testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
-            VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+        vibrator = IVibrator::getService(GetParam());
         ASSERT_NE(vibrator, nullptr);
     }
 
@@ -80,7 +65,7 @@
             << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
 }
 
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1) {
     vibrator->perform_1_1(Effect_1_1::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
     vibrator->perform_1_1(Effect_1_1::TICK, EffectStrength::STRONG, validatePerformEffect);
 }
@@ -88,7 +73,7 @@
 /*
  * Test to make sure effect values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_AboveValidRange) {
     Effect_1_1 effect = *std::prev(hidl_enum_range<Effect_1_1>().end());
     Effect_1_1 badEffect = static_cast<Effect_1_1>(static_cast<int32_t>(effect) + 1);
     EXPECT_OK(
@@ -98,7 +83,7 @@
 /*
  * Test to make sure effect values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_BelowValidRange) {
     Effect_1_1 effect = *hidl_enum_range<Effect_1_1>().begin();
     Effect_1_1 badEffect = static_cast<Effect_1_1>(static_cast<int32_t>(effect) - 1);
     EXPECT_OK(
@@ -108,7 +93,7 @@
 /*
  * Test to make sure strength values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_AboveValidRange) {
     EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
     EXPECT_OK(vibrator->perform_1_1(Effect_1_1::CLICK, badStrength, validatePerformEffectBadInput));
@@ -117,17 +102,13 @@
 /*
  * Test to make sure strength values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_BelowValidRange) {
     EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
     EXPECT_OK(vibrator->perform_1_1(Effect_1_1::CLICK, badStrength, validatePerformEffectBadInput));
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    VibratorHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, VibratorHidlTest_1_1,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.2/vts/functional/Android.bp b/vibrator/1.2/vts/functional/Android.bp
index 1e3ec97..e7052f2 100644
--- a/vibrator/1.2/vts/functional/Android.bp
+++ b/vibrator/1.2/vts/functional/Android.bp
@@ -23,6 +23,6 @@
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
 
diff --git a/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp b/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
index d69695a..2058e85 100644
--- a/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
+++ b/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
@@ -16,12 +16,13 @@
 
 #define LOG_TAG "vibrator_hidl_hal_test"
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/vibrator/1.0/types.h>
 #include <android/hardware/vibrator/1.2/IVibrator.h>
 #include <android/hardware/vibrator/1.2/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <unistd.h>
 
 using ::android::hardware::vibrator::V1_0::Status;
@@ -35,27 +36,11 @@
 
 #define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
 
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static VibratorHidlEnvironment* Instance() {
-        static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
-   private:
-    VibratorHidlEnvironment() {}
-};
-
 // The main test class for VIBRATOR HIDL HAL 1.2.
-class VibratorHidlTest_1_2 : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest_1_2 : public ::testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
-            VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+        vibrator = IVibrator::getService(GetParam());
         ASSERT_NE(vibrator, nullptr);
     }
 
@@ -85,7 +70,7 @@
  * Test to make sure effects within the valid range return are either supported and return OK with
  * a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
  */
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2) {
     for (const auto& effect : hidl_enum_range<Effect>()) {
         for (const auto& strength : hidl_enum_range<EffectStrength>()) {
             EXPECT_OK(vibrator->perform_1_2(effect, strength, validatePerformEffect));
@@ -96,7 +81,7 @@
 /*
  * Test to make sure effect values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_AboveValidRange) {
     Effect effect = *std::prev(hidl_enum_range<Effect>().end());
     Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
     EXPECT_OK(
@@ -106,7 +91,7 @@
 /*
  * Test to make sure effect values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_BelowValidRange) {
     Effect effect = *hidl_enum_range<Effect>().begin();
     Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
     EXPECT_OK(
@@ -116,7 +101,7 @@
 /*
  * Test to make sure strength values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_AboveValidRange) {
     EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
     EXPECT_OK(vibrator->perform_1_2(Effect::THUD, badStrength, validatePerformEffectBadInput));
@@ -125,17 +110,13 @@
 /*
  * Test to make sure strength values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_BelowValidRange) {
     EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
     EXPECT_OK(vibrator->perform_1_2(Effect::THUD, badStrength, validatePerformEffectBadInput));
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    VibratorHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, VibratorHidlTest_1_2,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.3/vts/functional/Android.bp b/vibrator/1.3/vts/functional/Android.bp
index 5b4c893..038dc5c 100644
--- a/vibrator/1.3/vts/functional/Android.bp
+++ b/vibrator/1.3/vts/functional/Android.bp
@@ -24,6 +24,6 @@
         "android.hardware.vibrator@1.2",
         "android.hardware.vibrator@1.3",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
 
diff --git a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
index 818f9c7..3cd3430 100644
--- a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
+++ b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
@@ -16,11 +16,12 @@
 
 #define LOG_TAG "vibrator_hidl_hal_test"
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/vibrator/1.0/types.h>
 #include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <unistd.h>
 
 using ::android::sp;
@@ -34,27 +35,11 @@
 
 #define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
 
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static VibratorHidlEnvironment* Instance() {
-        static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
-   private:
-    VibratorHidlEnvironment() {}
-};
-
 // The main test class for VIBRATOR HIDL HAL 1.3.
-class VibratorHidlTest_1_3 : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest_1_3 : public ::testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
-            VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+        vibrator = IVibrator::getService(GetParam());
         ASSERT_NE(vibrator, nullptr);
     }
 
@@ -63,7 +48,7 @@
     sp<IVibrator> vibrator;
 };
 
-TEST_F(VibratorHidlTest_1_3, ChangeVibrationalExternalControl) {
+TEST_P(VibratorHidlTest_1_3, ChangeVibrationalExternalControl) {
     if (vibrator->supportsExternalControl()) {
         EXPECT_EQ(Status::OK, vibrator->setExternalControl(true));
         sleep(1);
@@ -72,7 +57,7 @@
     }
 }
 
-TEST_F(VibratorHidlTest_1_3, SetExternalControlReturnUnsupportedOperationIfNotSupported) {
+TEST_P(VibratorHidlTest_1_3, SetExternalControlReturnUnsupportedOperationIfNotSupported) {
     if (!vibrator->supportsExternalControl()) {
         EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setExternalControl(true));
     }
@@ -98,7 +83,7 @@
  * Test to make sure effects within the valid range return are either supported and return OK with
  * a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
  */
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3) {
     for (const auto& effect : hidl_enum_range<Effect>()) {
         for (const auto& strength : hidl_enum_range<EffectStrength>()) {
             EXPECT_OK(vibrator->perform_1_3(effect, strength, validatePerformEffect));
@@ -109,7 +94,7 @@
 /*
  * Test to make sure effect values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_AboveValidRange) {
     Effect effect = *std::prev(hidl_enum_range<Effect>().end());
     Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
     EXPECT_OK(vibrator->perform_1_3(badEffect, EffectStrength::LIGHT,
@@ -119,7 +104,7 @@
 /*
  * Test to make sure effect values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_BelowValidRange) {
     Effect effect = *hidl_enum_range<Effect>().begin();
     Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
     EXPECT_OK(vibrator->perform_1_3(badEffect, EffectStrength::LIGHT,
@@ -129,7 +114,7 @@
 /*
  * Test to make sure strength values above the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_AboveValidRange) {
     EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
     EXPECT_OK(vibrator->perform_1_3(Effect::THUD, badStrength,
@@ -139,18 +124,14 @@
 /*
  * Test to make sure strength values below the valid range are rejected.
  */
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_BelowValidRange) {
     EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
     EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
     EXPECT_OK(vibrator->perform_1_3(Effect::THUD, badStrength,
                                     validatePerformEffectUnsupportedOperation));
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    VibratorHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, VibratorHidlTest_1_3,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.4/vts/functional/Android.bp b/vibrator/1.4/vts/functional/Android.bp
index 4cdf3b6..202a824 100644
--- a/vibrator/1.4/vts/functional/Android.bp
+++ b/vibrator/1.4/vts/functional/Android.bp
@@ -25,6 +25,9 @@
         "android.hardware.vibrator@1.3",
         "android.hardware.vibrator@1.4",
     ],
-    test_suites: ["general-tests"],
+    test_suites: [
+        "general-tests",
+        "vts-core",
+    ],
 }
 
diff --git a/wifi/1.4/IWifi.hal b/wifi/1.4/IWifi.hal
index f4bc618..765e09d 100644
--- a/wifi/1.4/IWifi.hal
+++ b/wifi/1.4/IWifi.hal
@@ -24,5 +24,4 @@
  * module loaded in the system.
  * IWifi.getChip() must return @1.2::IWifiChip
  */
-interface IWifi extends @1.3::IWifi {
-};
+interface IWifi extends @1.3::IWifi {};
diff --git a/wifi/supplicant/1.3/ISupplicant.hal b/wifi/supplicant/1.3/ISupplicant.hal
index 75b7e96..246ce1f 100644
--- a/wifi/supplicant/1.3/ISupplicant.hal
+++ b/wifi/supplicant/1.3/ISupplicant.hal
@@ -26,5 +26,4 @@
  * 1.2 HAL. For example V1_2::ISupplicant::addIface() adds V1_2::ISupplicantIface,
  * which can be cast to V1_3::ISupplicantStaIface.
  */
-interface ISupplicant extends @1.2::ISupplicant {
-};
+interface ISupplicant extends @1.2::ISupplicant {};
diff --git a/wifi/supplicant/1.3/ISupplicantStaIface.hal b/wifi/supplicant/1.3/ISupplicantStaIface.hal
index 62b4033..cb207d8 100644
--- a/wifi/supplicant/1.3/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaIface.hal
@@ -18,7 +18,7 @@
 
 import @1.0::SupplicantStatus;
 import @1.2::ISupplicantStaIface;
-import @1.3::ISupplicantStaIfaceCallback;
+import ISupplicantStaIfaceCallback;
 
 /**
  * Interface exposed by the supplicant for each station mode network
@@ -43,4 +43,15 @@
      */
     registerCallback_1_3(ISupplicantStaIfaceCallback callback)
         generates (SupplicantStatus status);
+
+    /**
+     * Get Connection capabilities
+     *
+     * @return status Status of the operation, and connection capabilities.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     */
+    getConnectionCapabilities()
+        generates (SupplicantStatus status, ConnectionCapabilities capabilities);
 };
diff --git a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
index 5e265c6..ab08cff 100644
--- a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
@@ -60,6 +60,5 @@
      *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
      *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
      */
-    setPmkCache(vec<uint8_t> serializedEntry)
-        generates (SupplicantStatus status);
+    setPmkCache(vec<uint8_t> serializedEntry) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.3/types.hal b/wifi/supplicant/1.3/types.hal
index a782b49..7874399 100644
--- a/wifi/supplicant/1.3/types.hal
+++ b/wifi/supplicant/1.3/types.hal
@@ -25,3 +25,36 @@
     REQUIRE_CERT_STATUS,
     REQUIRE_ALL_CERTS_STATUS,
 };
+
+/**
+ * Wifi Technologies
+ */
+enum WifiTechnology : uint32_t {
+    UNKNOWN = 0,
+    /**
+     * For 802.11a/b/g
+     */
+    LEGACY = 1,
+    /**
+     * For 802.11n
+     */
+    HT = 2,
+    /**
+     * For 802.11ac
+     */
+    VHT = 3,
+    /**
+     * For 802.11ax
+     */
+    HE = 4,
+};
+
+/**
+ * Connection Capabilities.
+ */
+struct ConnectionCapabilities {
+    /**
+     * Wifi Technology
+     */
+    WifiTechnology technology;
+};
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 9b68a47..62f3228 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -37,6 +37,7 @@
 using ::android::hardware::wifi::supplicant::V1_2::DppAkm;
 using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode;
 using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode;
+using ::android::hardware::wifi::supplicant::V1_3::ConnectionCapabilities;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIfaceCallback;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
@@ -179,3 +180,14 @@
             EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
         });
 }
+
+/*
+ * getConnectionCapabilities
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) {
+    sta_iface_->getConnectionCapabilities(
+        [&](const SupplicantStatus& status,
+            ConnectionCapabilities /* capabilities */) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}