diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 13c53ba..330a470 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -27,6 +27,7 @@
 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
 #include <CameraMetadata.h>
 #include <CameraParameters.h>
@@ -97,8 +98,9 @@
 using ::android::hardware::MessageQueue;
 using ::android::hardware::kSynchronizedReadWrite;
 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using ::android::hidl::manager::V1_0::IServiceManager;
 
-const char kCameraLegacyServiceName[] = "legacy/0";
+const char *kProviderFQName = "android.hardware.camera.provider@2.4::ICameraProvider";
 const uint32_t kMaxPreviewWidth = 1920;
 const uint32_t kMaxPreviewHeight = 1080;
 const uint32_t kMaxVideoWidth = 4096;
@@ -122,21 +124,25 @@
 
 namespace {
     // "device@<version>/legacy/<id>"
-    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/legacy/(.+)";
+    const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
     const char *kHAL3_2 = "3.2";
     const char *kHAL1_0 = "1.0";
 
-    bool matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
-        std::regex e(kDeviceNameRE);
+    bool matchDeviceName(const hidl_string& deviceName,
+            const hidl_string &providerType, std::smatch& sm) {
+        ::android::String8 pattern;
+        pattern.appendFormat(kDeviceNameRE, providerType.c_str());
+        std::regex e(pattern.string());
         std::string deviceNameStd(deviceName.c_str());
         return std::regex_match(deviceNameStd, sm, e);
     }
 
-    int getCameraDeviceVersion(const hidl_string& deviceName) {
+    int getCameraDeviceVersion(const hidl_string& deviceName,
+            const hidl_string &providerType) {
         std::smatch sm;
-        bool match = matchDeviceName(deviceName, sm);
+        bool match = matchDeviceName(deviceName, providerType, sm);
         if (!match) {
             return -1;
         }
@@ -150,6 +156,45 @@
         return 0;
     }
 
+    bool parseProviderName(const std::string& name, std::string *type /*out*/,
+            uint32_t *id /*out*/) {
+        if (!type || !id) {
+            ADD_FAILURE();
+            return false;
+        }
+
+        std::string::size_type slashIdx = name.find('/');
+        if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
+            ADD_FAILURE() << "Provider name does not have / separator between type"
+                    "and id";
+            return false;
+        }
+
+        std::string typeVal = name.substr(0, slashIdx);
+
+        char *endPtr;
+        errno = 0;
+        long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
+        if (errno != 0) {
+            ADD_FAILURE() << "cannot parse provider id as an integer:" <<
+                    name.c_str() << strerror(errno) << errno;
+            return false;
+        }
+        if (endPtr != name.c_str() + name.size()) {
+            ADD_FAILURE() << "provider id has unexpected length " << name.c_str();
+            return false;
+        }
+        if (idVal < 0) {
+            ADD_FAILURE() << "id is negative: " << name.c_str() << idVal;
+            return false;
+        }
+
+        *type = typeVal;
+        *id = static_cast<uint32_t>(idVal);
+
+        return true;
+    }
+
     Status mapToStatus(::android::status_t s)  {
         switch(s) {
             case ::android::OK:
@@ -184,7 +229,7 @@
     virtual void SetUp() override;
     virtual void TearDown() override;
 
-    sp<ICameraProvider> mProvider;
+    std::unordered_map<std::string, sp<ICameraProvider> > mProviders;
 
 private:
     CameraHidlEnvironment() {}
@@ -193,9 +238,26 @@
 };
 
 void CameraHidlEnvironment::SetUp() {
-    mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(kCameraLegacyServiceName);
-    ALOGI_IF(mProvider, "provider is not nullptr, %p", mProvider.get());
-    ASSERT_NE(mProvider, nullptr);
+    sp<IServiceManager> manager = IServiceManager::getService();
+    ASSERT_NE(manager, nullptr);
+
+    manager->listByInterface(kProviderFQName,
+                             [this](const hidl_vec<hidl_string> &registered) {
+        std::string name;
+        uint32_t id;
+        sp<ICameraProvider> provider = nullptr;
+        for (size_t i = 0; i < registered.size(); i++) {
+            ASSERT_TRUE(parseProviderName(registered[i],
+                    &name /*out*/, &id /*out*/));
+            provider = ICameraProvider::tryGetService(registered[i]);
+            ALOGI_IF(provider, "provider is not nullptr, %p", provider.get());
+            if (nullptr != provider.get()) {
+                mProviders.emplace(name, provider);
+            }
+        }
+    });
+
+    ASSERT_FALSE(mProviders.empty());
 }
 
 void CameraHidlEnvironment::TearDown() {
@@ -447,7 +509,7 @@
     virtual void SetUp() override {}
     virtual void TearDown() override {}
 
-    hidl_vec<hidl_string> getCameraDeviceNames();
+    hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider);
 
     struct EmptyDeviceCb : public ICameraDeviceCallback {
         virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override {
@@ -523,7 +585,7 @@
         CameraHidlTest *mParent;               // Parent object
     };
 
-    void openCameraDevice(const std::string &name,const CameraHidlEnvironment* env,
+    void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
             sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
     void setupPreviewWindow(
             const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
@@ -546,11 +608,11 @@
     void waitForFrameLocked(DataCallbackMsg msgFrame,
             std::unique_lock<std::mutex> &l);
     void openEmptyDeviceSession(const std::string &name,
-            const CameraHidlEnvironment* env,
+            sp<ICameraProvider> provider,
             sp<ICameraDeviceSession> *session /*out*/,
             camera_metadata_t **staticMeta /*out*/);
     void configurePreviewStream(const std::string &name,
-            const CameraHidlEnvironment* env,
+            sp<ICameraProvider> provider,
             const AvailableStream *previewThreshold,
             sp<ICameraDeviceSession> *session /*out*/,
             Stream *previewStream /*out*/,
@@ -934,11 +996,10 @@
     return Void();
 }
 
-hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames() {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
+hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) {
     hidl_vec<hidl_string> cameraDeviceNames;
     Return<void> ret;
-    ret = env->mProvider->getCameraIdList(
+    ret = provider->getCameraIdList(
         [&](auto status, const auto& idList) {
             ALOGI("getCameraIdList returns status:%d", (int)status);
             for (size_t i = 0; i < idList.size(); i++) {
@@ -956,58 +1017,63 @@
 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
 TEST_F(CameraHidlTest, isTorchModeSupported) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
-        [&](auto status, bool support) {
-            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
-                    (int)status, support);
-            ASSERT_EQ(Status::OK, status);
-        });
-    ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->isSetTorchModeSupported(
+            [&](auto status, bool support) {
+                ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
+                        (int)status, support);
+                ASSERT_EQ(Status::OK, status);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
 TEST_F(CameraHidlTest, getCameraIdList) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->getCameraIdList(
-        [&](auto status, const auto& idList) {
-            ALOGI("getCameraIdList returns status:%d", (int)status);
-            for (size_t i = 0; i < idList.size(); i++) {
-                ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
-            }
-            ASSERT_EQ(Status::OK, status);
-            // This is true for internal camera provider.
-            // Not necessary hold for external cameras providers
-            ASSERT_GT(idList.size(), 0u);
-        });
-    ASSERT_TRUE(ret.isOk());
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->getCameraIdList(
+            [&](auto status, const auto& idList) {
+                ALOGI("getCameraIdList returns status:%d", (int)status);
+                for (size_t i = 0; i < idList.size(); i++) {
+                    ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
+                }
+                ASSERT_EQ(Status::OK, status);
+                // This is true for internal camera provider.
+                // Not necessary hold for external cameras providers
+                ASSERT_GT(idList.size(), 0u);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // Test if ICameraProvider::getVendorTags returns Status::OK
 TEST_F(CameraHidlTest, getVendorTags) {
     Return<void> ret;
-    ret = CameraHidlEnvironment::Instance()->mProvider->getVendorTags(
-        [&](auto status, const auto& vendorTagSecs) {
-            ALOGI("getVendorTags returns status:%d numSections %zu",
-                    (int)status, vendorTagSecs.size());
-            for (size_t i = 0; i < vendorTagSecs.size(); i++) {
-                ALOGI("Vendor tag section %zu name %s",
-                        i, vendorTagSecs[i].sectionName.c_str());
-                for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
-                    const auto& tag = vendorTagSecs[i].tags[j];
-                    ALOGI("Vendor tag id %u name %s type %d",
-                            tag.tagId,
-                            tag.tagName.c_str(),
-                            (int) tag.tagType);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        ret = provider.second->getVendorTags(
+            [&](auto status, const auto& vendorTagSecs) {
+                ALOGI("getVendorTags returns status:%d numSections %zu",
+                        (int)status, vendorTagSecs.size());
+                for (size_t i = 0; i < vendorTagSecs.size(); i++) {
+                    ALOGI("Vendor tag section %zu name %s",
+                            i, vendorTagSecs[i].sectionName.c_str());
+                    for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
+                        const auto& tag = vendorTagSecs[i].tags[j];
+                        ALOGI("Vendor tag id %u name %s type %d",
+                                tag.tagId,
+                                tag.tagName.c_str(),
+                                (int) tag.tagType);
+                    }
                 }
-            }
-            ASSERT_EQ(Status::OK, status);
-        });
-    ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::OK, status);
+            });
+        ASSERT_TRUE(ret.isOk());
+    }
 }
 
 // Test if ICameraProvider::setCallback returns Status::OK
 TEST_F(CameraHidlTest, setCallback) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
     struct ProviderCb : public ICameraProviderCallback {
         virtual Return<void> cameraDeviceStatusChange(
                 const hidl_string& cameraDeviceName,
@@ -1026,37 +1092,45 @@
         }
     };
     sp<ProviderCb> cb = new ProviderCb;
-    auto status = env->mProvider->setCallback(cb);
-    ASSERT_TRUE(status.isOk());
-    ASSERT_EQ(Status::OK, status);
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        auto status = provider.second->setCallback(cb);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_EQ(Status::OK, status);
+    }
 }
 
 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device3_2) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device3_2, nullptr);
-                });
-            ASSERT_TRUE(ret.isOk());
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device1) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device1, nullptr);
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device3_2) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device3_2, nullptr);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device1) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device1, nullptr);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1064,60 +1138,66 @@
 // Verify that the device resource cost can be retrieved and the values are
 // sane.
 TEST_F(CameraHidlTest, getResourceCost) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device3_2->getResourceCost(
-                [&](auto status, const auto& resourceCost) {
-                    ALOGI("getResourceCost returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
-                    ASSERT_LE(resourceCost.resourceCost, 100u);
-                    for (const auto& name : resourceCost.conflictingDevices) {
-                        ALOGI("    Conflicting device: %s", name.c_str());
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
-        } else {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getResourceCost: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device3_2->getResourceCost(
+                    [&](auto status, const auto& resourceCost) {
+                        ALOGI("getResourceCost returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ALOGI("    Resource cost is %d", resourceCost.resourceCost);
+                        ASSERT_LE(resourceCost.resourceCost, 100u);
+                        for (const auto& name : resourceCost.conflictingDevices) {
+                            ALOGI("    Conflicting device: %s", name.c_str());
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            } else {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getResourceCost: Testing camera device %s", name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device1->getResourceCost(
-                [&](auto status, const auto& resourceCost) {
-                    ALOGI("getResourceCost returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ALOGI("    Resource cost is %d", resourceCost.resourceCost);
-                    ASSERT_LE(resourceCost.resourceCost, 100u);
-                    for (const auto& name : resourceCost.conflictingDevices) {
-                        ALOGI("    Conflicting device: %s", name.c_str());
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->getResourceCost(
+                    [&](auto status, const auto& resourceCost) {
+                        ALOGI("getResourceCost returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ALOGI("    Resource cost is %d",
+                              resourceCost.resourceCost);
+                        ASSERT_LE(resourceCost.resourceCost, 100u);
+                        for (const auto& name : resourceCost.conflictingDevices) {
+                            ALOGI("    Conflicting device: %s", name.c_str());
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1125,126 +1205,143 @@
 // Verify that the static camera info can be retrieved
 // successfully.
 TEST_F(CameraHidlTest, getCameraInfo) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device1->getCameraInfo(
-                [&](auto status, const auto& info) {
-                    ALOGI("getCameraInfo returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    switch(info.orientation) {
-                        case 0:
-                        case 90:
-                        case 180:
-                        case 270:
-                            //Expected cases
-                            ALOGI("camera orientation: %d", info.orientation);
-                            break;
-                        default:
-                            FAIL() << "Unexpected camera orientation:" << info.orientation;
-                    }
-                    switch(info.facing) {
-                        case CameraFacing::BACK:
-                        case CameraFacing::FRONT:
-                        case CameraFacing::EXTERNAL:
-                            //Expected cases
-                            ALOGI("camera facing: %d", info.facing);
-                            break;
-                        default:
-                            FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (info.facing);
-                    }
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->getCameraInfo(
+                    [&](auto status, const auto& info) {
+                        ALOGI("getCameraInfo returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        switch(info.orientation) {
+                            case 0:
+                            case 90:
+                            case 180:
+                            case 270:
+                                //Expected cases
+                                ALOGI("camera orientation: %d", info.orientation);
+                                break;
+                            default:
+                                FAIL() << "Unexpected camera orientation:" << info.orientation;
+                        }
+                        switch(info.facing) {
+                            case CameraFacing::BACK:
+                            case CameraFacing::FRONT:
+                            case CameraFacing::EXTERNAL:
+                                //Expected cases
+                                ALOGI("camera facing: %d", info.facing);
+                                break;
+                            default:
+                                FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> (
+                                        info.facing);
+                        }
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Check whether preview window can be configured
 TEST_F(CameraHidlTest, setPreviewWindow) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-                    openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1,
-                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1,
+                        &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
 
-            Return<void> ret;
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret;
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Verify that setting preview window fails in case device is not open
 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+                Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
+            }
         }
     }
 }
 
 // Start and stop preview checking whether it gets enabled in between.
 TEST_F(CameraHidlTest, startStopPreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-                    openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1,
-                    &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1,
+                        &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
 
-            startPreview(device1);
+                startPreview(device1);
 
-            Return<bool> returnBoolStatus = device1->previewEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                Return<bool> returnBoolStatus = device1->previewEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
@@ -1252,599 +1349,646 @@
 // Start preview without active preview window. Preview should start as soon
 // as a valid active window gets configured.
 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            startPreview(device1);
+                startPreview(device1);
 
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            //Preview should get enabled now
-            Return<bool> returnBoolStatus = device1->previewEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                //Preview should get enabled now
+                Return<bool> returnBoolStatus = device1->previewEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Verify that image capture behaves as expected along with preview callbacks.
 TEST_F(CameraHidlTest, takePicture) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
+
+                enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                              device1);
+                startPreview(device1);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                }
+
+                disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                                device1);
+                enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                        device1);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
+
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
+                }
+
+                disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
+                        device1);
+                stopPreviewAndClose(device1);
             }
-
-            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-            startPreview(device1);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
-            }
-
-            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
-                            device1);
-            enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
-                    device1);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
-
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
-            }
-
-            disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE,
-                    device1);
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Image capture should fail in case preview didn't get enabled first.
 TEST_F(CameraHidlTest, takePictureFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Verify that image capture can be cancelled.
 TEST_F(CameraHidlTest, cancelPicture) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            Return<Status> returnStatus = device1->takePicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->takePicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            returnStatus = device1->cancelPicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                returnStatus = device1->cancelPicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Image capture cancel should fail when image capture is not running.
 TEST_F(CameraHidlTest, cancelPictureFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
 
-            Return<Status> returnStatus = device1->cancelPicture();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->cancelPicture();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            stopPreviewAndClose(device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // Test basic video recording.
 TEST_F(CameraHidlTest, startStopRecording) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                }
 
-            enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-            startPreview(device1);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
-                mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
-                mVideoBufferIndex = UINT32_MAX;
-            }
-
-            disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
-
-            bool videoMetaEnabled = false;
-            Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
-            ASSERT_TRUE(returnStatus.isOk());
-            // It is allowed for devices to not support this feature
-            ASSERT_TRUE((Status::OK == returnStatus) ||
-                    (Status::OPERATION_NOT_SUPPORTED == returnStatus));
-            if (Status::OK == returnStatus) {
-                videoMetaEnabled = true;
-            }
-
-            enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
-            Return<bool> returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_FALSE(returnBoolStatus);
-
-            returnStatus = device1->startRecording();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
-                ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
-                disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
                         device1);
-            }
+                startPreview(device1);
 
-            returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_TRUE(returnBoolStatus);
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
+                    mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
+                    mVideoBufferIndex = UINT32_MAX;
+                }
 
-            Return<void> ret;
-            if (videoMetaEnabled) {
-                ret = device1->releaseRecordingFrameHandle(mVideoData,
-                        mVideoBufferIndex, mVideoNativeHandle);
+                disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME,
+                        device1);
+
+                bool videoMetaEnabled = false;
+                Return<Status> returnStatus = device1->storeMetaDataInBuffers(
+                        true);
+                ASSERT_TRUE(returnStatus.isOk());
+                // It is allowed for devices to not support this feature
+                ASSERT_TRUE((Status::OK == returnStatus) ||
+                        (Status::OPERATION_NOT_SUPPORTED == returnStatus));
+                if (Status::OK == returnStatus) {
+                    videoMetaEnabled = true;
+                }
+
+                enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                        device1);
+                Return<bool> returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_FALSE(returnBoolStatus);
+
+                returnStatus = device1->startRecording();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
+                    ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
+                    disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME,
+                            device1);
+                }
+
+                returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_TRUE(returnBoolStatus);
+
+                Return<void> ret;
+                if (videoMetaEnabled) {
+                    ret = device1->releaseRecordingFrameHandle(mVideoData,
+                            mVideoBufferIndex, mVideoNativeHandle);
+                    ASSERT_TRUE(ret.isOk());
+                } else {
+                    ret = device1->releaseRecordingFrame(mVideoData,
+                            mVideoBufferIndex);
+                    ASSERT_TRUE(ret.isOk());
+                }
+
+                ret = device1->stopRecording();
                 ASSERT_TRUE(ret.isOk());
-            } else {
-                ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
-                ASSERT_TRUE(ret.isOk());
+
+                stopPreviewAndClose(device1);
             }
-
-            ret = device1->stopRecording();
-            ASSERT_TRUE(ret.isOk());
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // It shouldn't be possible to start recording without enabling preview first.
 TEST_F(CameraHidlTest, startRecordingFail) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            Return<bool> returnBoolStatus = device1->recordingEnabled();
-            ASSERT_TRUE(returnBoolStatus.isOk());
-            ASSERT_FALSE(returnBoolStatus);
+                Return<bool> returnBoolStatus = device1->recordingEnabled();
+                ASSERT_TRUE(returnBoolStatus.isOk());
+                ASSERT_FALSE(returnBoolStatus);
 
-            Return<Status> returnStatus = device1->startRecording();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_NE(Status::OK, returnStatus);
+                Return<Status> returnStatus = device1->startRecording();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_NE(Status::OK, returnStatus);
 
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Check autofocus support if available.
 TEST_F(CameraHidlTest, autoFocus) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
-            CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
-            CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
+                CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
+                CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                    CameraParameters::FOCUS_MODE_AUTO)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-            enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
-
-            for (auto &iter : focusModes) {
                 if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                        iter)) {
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
                     continue;
                 }
 
-                cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
-                setParameters(device1, cameraParams);
-                {
-                    std::unique_lock<std::mutex> l(mLock);
-                    mNotifyMessage = NotifyCallbackMsg::ERROR;
-                }
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+                enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
 
-                Return<Status> returnStatus = device1->autoFocus();
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
+                for (auto &iter : focusModes) {
+                    if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                            iter)) {
+                        continue;
+                    }
 
-                {
-                    std::unique_lock<std::mutex> l(mLock);
-                    while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
-                        auto timeout = std::chrono::system_clock::now() +
-                                std::chrono::seconds(kAutoFocusTimeoutSec);
-                        ASSERT_NE(std::cv_status::timeout,
-                                mResultCondition.wait_until(l, timeout));
+                    cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
+                    setParameters(device1, cameraParams);
+                    {
+                        std::unique_lock<std::mutex> l(mLock);
+                        mNotifyMessage = NotifyCallbackMsg::ERROR;
+                    }
+
+                    Return<Status> returnStatus = device1->autoFocus();
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+
+                    {
+                        std::unique_lock<std::mutex> l(mLock);
+                        while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
+                            auto timeout = std::chrono::system_clock::now() +
+                                    std::chrono::seconds(kAutoFocusTimeoutSec);
+                            ASSERT_NE(std::cv_status::timeout,
+                                    mResultCondition.wait_until(l, timeout));
+                        }
                     }
                 }
-            }
 
-            disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
-            stopPreviewAndClose(device1);
+                disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
+                stopPreviewAndClose(device1);
+            }
         }
     }
 }
 
 // In case autofocus is supported verify that it can be cancelled.
 TEST_F(CameraHidlTest, cancelAutoFocus) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            if (Status::OK != isAutoFocusModeAvailable(cameraParams,
-                    CameraParameters::FOCUS_MODE_AUTO)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
+                if (Status::OK != isAutoFocusModeAvailable(cameraParams,
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+
+                // It should be fine to call before preview starts.
+                ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
+
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+
+                // It should be fine to call after preview starts too.
+                Return<Status> returnStatus = device1->cancelAutoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                returnStatus = device1->autoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                returnStatus = device1->cancelAutoFocus();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                stopPreviewAndClose(device1);
             }
-
-            // It should be fine to call before preview starts.
-            ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-
-            // It should be fine to call after preview starts too.
-            Return<Status> returnStatus = device1->cancelAutoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            returnStatus = device1->autoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            returnStatus = device1->cancelAutoFocus();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Check whether face detection is available and try to enable&disable.
 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            int32_t hwFaces = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
-            int32_t swFaces = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
-            if ((0 >= hwFaces) && (0 >= swFaces)) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
+                int32_t hwFaces = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
+                int32_t swFaces = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
+                if ((0 >= hwFaces) && (0 >= swFaces)) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+
+                if (0 < hwFaces) {
+                    Return<Status> returnStatus = device1->sendCommand(
+                            CommandType::START_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_HW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    // TODO(epeev) : Enable and check for face notifications
+                    returnStatus = device1->sendCommand(
+                            CommandType::STOP_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_HW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                }
+
+                if (0 < swFaces) {
+                    Return<Status> returnStatus = device1->sendCommand(
+                            CommandType::START_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_SW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    // TODO(epeev) : Enable and check for face notifications
+                    returnStatus = device1->sendCommand(
+                            CommandType::STOP_FACE_DETECTION,
+                            CAMERA_FACE_DETECTION_SW, 0);
+                    ASSERT_TRUE(returnStatus.isOk());
+                    ASSERT_EQ(Status::OK, returnStatus);
+                }
+
+                stopPreviewAndClose(device1);
             }
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-
-            if (0 < hwFaces) {
-                Return<Status> returnStatus = device1->sendCommand(
-                        CommandType::START_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_HW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-                // TODO(epeev) : Enable and check for face notifications
-                returnStatus = device1->sendCommand(
-                        CommandType::STOP_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_HW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-            }
-
-            if (0 < swFaces) {
-                Return<Status> returnStatus = device1->sendCommand(
-                        CommandType::START_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_SW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-                // TODO(epeev) : Enable and check for face notifications
-                returnStatus = device1->sendCommand(
-                        CommandType::STOP_FACE_DETECTION,
-                        CAMERA_FACE_DETECTION_SW, 0);
-                ASSERT_TRUE(returnStatus.isOk());
-                ASSERT_EQ(Status::OK, returnStatus);
-            }
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Check whether smooth zoom is available and try to enable&disable.
 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            const char *smoothZoomStr = cameraParams.get(
-                    CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
-            bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
-                    (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
-                            true : false;
-            if (!smoothZoomSupported) {
-                Return<void> ret = device1->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
+                const char *smoothZoomStr = cameraParams.get(
+                        CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
+                bool smoothZoomSupported = ((nullptr != smoothZoomStr) &&
+                        (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ?
+                                true : false;
+                if (!smoothZoomSupported) {
+                    Return<void> ret = device1->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+
+                int32_t maxZoom = cameraParams.getInt(
+                        CameraParameters::KEY_MAX_ZOOM);
+                ASSERT_TRUE(0 < maxZoom);
+
+                sp<BufferItemConsumer> bufferItemConsumer;
+                sp<BufferItemHander> bufferHandler;
+                setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
+                        &bufferHandler /*out*/);
+                startPreview(device1);
+                setParameters(device1, cameraParams);
+
+                Return<Status> returnStatus = device1->sendCommand(
+                        CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                // TODO(epeev) : Enable and check for face notifications
+                returnStatus = device1->sendCommand(
+                        CommandType::STOP_SMOOTH_ZOOM, 0, 0);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                stopPreviewAndClose(device1);
             }
-
-            int32_t maxZoom = cameraParams.getInt(
-                    CameraParameters::KEY_MAX_ZOOM);
-            ASSERT_TRUE(0 < maxZoom);
-
-            sp<BufferItemConsumer> bufferItemConsumer;
-            sp<BufferItemHander> bufferHandler;
-            setupPreviewWindow(device1, &bufferItemConsumer /*out*/,
-                    &bufferHandler /*out*/);
-            startPreview(device1);
-            setParameters(device1, cameraParams);
-
-            Return<Status> returnStatus = device1->sendCommand(
-                    CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            // TODO(epeev) : Enable and check for face notifications
-            returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM,
-                    0, 0);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-
-            stopPreviewAndClose(device1);
         }
     }
 }
 
 // Basic sanity tests related to camera parameters.
 TEST_F(CameraHidlTest, getSetParameters) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            CameraParameters cameraParams;
-            getParameters(device1, &cameraParams /*out*/);
+                CameraParameters cameraParams;
+                getParameters(device1, &cameraParams /*out*/);
 
-            int32_t width, height;
-            cameraParams.getPictureSize(&width, &height);
-            ASSERT_TRUE((0 < width) && (0 < height));
-            cameraParams.getPreviewSize(&width, &height);
-            ASSERT_TRUE((0 < width) && (0 < height));
-            int32_t minFps, maxFps;
-            cameraParams.getPreviewFpsRange(&minFps, &maxFps);
-            ASSERT_TRUE((0 < minFps) && (0 < maxFps));
-            ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
-            ASSERT_NE(nullptr, cameraParams.getPictureFormat());
-            ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
-                    cameraParams.getPictureFormat()) == 0);
+                int32_t width, height;
+                cameraParams.getPictureSize(&width, &height);
+                ASSERT_TRUE((0 < width) && (0 < height));
+                cameraParams.getPreviewSize(&width, &height);
+                ASSERT_TRUE((0 < width) && (0 < height));
+                int32_t minFps, maxFps;
+                cameraParams.getPreviewFpsRange(&minFps, &maxFps);
+                ASSERT_TRUE((0 < minFps) && (0 < maxFps));
+                ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
+                ASSERT_NE(nullptr, cameraParams.getPictureFormat());
+                ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG,
+                        cameraParams.getPictureFormat()) == 0);
 
-            const char *flashMode = cameraParams.get(
-                    CameraParameters::KEY_FLASH_MODE);
-            ASSERT_TRUE((nullptr == flashMode) || (strcmp(
-                    CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
+                const char *flashMode = cameraParams.get(
+                        CameraParameters::KEY_FLASH_MODE);
+                ASSERT_TRUE((nullptr == flashMode) || (strcmp(
+                        CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
 
-            const char *wbMode = cameraParams.get(
-                    CameraParameters::KEY_WHITE_BALANCE);
-            ASSERT_TRUE((nullptr == wbMode) || (strcmp(
-                    CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
+                const char *wbMode = cameraParams.get(
+                        CameraParameters::KEY_WHITE_BALANCE);
+                ASSERT_TRUE((nullptr == wbMode) || (strcmp(
+                        CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
 
-            const char *effect = cameraParams.get(CameraParameters::KEY_EFFECT);
-            ASSERT_TRUE((nullptr == effect) || (strcmp(
-                    CameraParameters::EFFECT_NONE, effect) == 0));
+                const char *effect = cameraParams.get(
+                        CameraParameters::KEY_EFFECT);
+                ASSERT_TRUE((nullptr == effect) || (strcmp(
+                        CameraParameters::EFFECT_NONE, effect) == 0));
 
-            ::android::Vector<Size> previewSizes;
-            cameraParams.getSupportedPreviewSizes(previewSizes);
-            ASSERT_FALSE(previewSizes.empty());
-            ::android::Vector<Size> pictureSizes;
-            cameraParams.getSupportedPictureSizes(pictureSizes);
-            ASSERT_FALSE(pictureSizes.empty());
-            const char *previewFormats = cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
-            ASSERT_NE(nullptr, previewFormats);
-            ::android::String8 previewFormatsString(previewFormats);
-            ASSERT_TRUE(previewFormatsString.contains(
-                    CameraParameters::PIXEL_FORMAT_YUV420SP));
-            ASSERT_NE(nullptr, cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
-            ASSERT_NE(nullptr, cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
-            const char *focusModes = cameraParams.get(
-                    CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
-            ASSERT_NE(nullptr, focusModes);
-            ::android::String8 focusModesString(focusModes);
-            const char *focusMode = cameraParams.get(
-                    CameraParameters::KEY_FOCUS_MODE);
-            ASSERT_NE(nullptr, focusMode);
-            // Auto focus mode should be default
-            if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
-                ASSERT_TRUE(strcmp(
-                        CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+                ::android::Vector<Size> previewSizes;
+                cameraParams.getSupportedPreviewSizes(previewSizes);
+                ASSERT_FALSE(previewSizes.empty());
+                ::android::Vector<Size> pictureSizes;
+                cameraParams.getSupportedPictureSizes(pictureSizes);
+                ASSERT_FALSE(pictureSizes.empty());
+                const char *previewFormats = cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+                ASSERT_NE(nullptr, previewFormats);
+                ::android::String8 previewFormatsString(previewFormats);
+                ASSERT_TRUE(previewFormatsString.contains(
+                        CameraParameters::PIXEL_FORMAT_YUV420SP));
+                ASSERT_NE(nullptr, cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
+                ASSERT_NE(nullptr, cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
+                const char *focusModes = cameraParams.get(
+                        CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
+                ASSERT_NE(nullptr, focusModes);
+                ::android::String8 focusModesString(focusModes);
+                const char *focusMode = cameraParams.get(
+                        CameraParameters::KEY_FOCUS_MODE);
+                ASSERT_NE(nullptr, focusMode);
+                // Auto focus mode should be default
+                if (focusModesString.contains(
+                        CameraParameters::FOCUS_MODE_AUTO)) {
+                    ASSERT_TRUE(strcmp(
+                            CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
+                }
+                ASSERT_TRUE(0 < cameraParams.getInt(
+                        CameraParameters::KEY_FOCAL_LENGTH));
+                int32_t horizontalViewAngle = cameraParams.getInt(
+                        CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
+                ASSERT_TRUE((0 < horizontalViewAngle) &&
+                            (360 >= horizontalViewAngle));
+                int32_t verticalViewAngle = cameraParams.getInt(
+                        CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
+                ASSERT_TRUE((0 < verticalViewAngle) &&
+                            (360 >= verticalViewAngle));
+                int32_t jpegQuality = cameraParams.getInt(
+                        CameraParameters::KEY_JPEG_QUALITY);
+                ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
+                int32_t jpegThumbQuality = cameraParams.getInt(
+                        CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
+                ASSERT_TRUE((1 <= jpegThumbQuality) &&
+                            (100 >= jpegThumbQuality));
+
+                cameraParams.setPictureSize(pictureSizes[0].width,
+                        pictureSizes[0].height);
+                cameraParams.setPreviewSize(previewSizes[0].width,
+                        previewSizes[0].height);
+
+                setParameters(device1, cameraParams);
+                getParameters(device1, &cameraParams /*out*/);
+
+                cameraParams.getPictureSize(&width, &height);
+                ASSERT_TRUE((pictureSizes[0].width == width) &&
+                        (pictureSizes[0].height == height));
+                cameraParams.getPreviewSize(&width, &height);
+                ASSERT_TRUE((previewSizes[0].width == width) &&
+                        (previewSizes[0].height == height));
+
+                Return<void> ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ASSERT_TRUE(0 < cameraParams.getInt(
-                    CameraParameters::KEY_FOCAL_LENGTH));
-            int32_t horizontalViewAngle = cameraParams.getInt(
-                    CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
-            ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
-            int32_t verticalViewAngle = cameraParams.getInt(
-                    CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
-            ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
-            int32_t jpegQuality = cameraParams.getInt(
-                    CameraParameters::KEY_JPEG_QUALITY);
-            ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
-            int32_t jpegThumbQuality = cameraParams.getInt(
-                    CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
-            ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
-
-            cameraParams.setPictureSize(pictureSizes[0].width,
-                    pictureSizes[0].height);
-            cameraParams.setPreviewSize(previewSizes[0].width,
-                    previewSizes[0].height);
-
-            setParameters(device1, cameraParams);
-            getParameters(device1, &cameraParams /*out*/);
-
-            cameraParams.getPictureSize(&width, &height);
-            ASSERT_TRUE((pictureSizes[0].width == width) &&
-                    (pictureSizes[0].height == height));
-            cameraParams.getPreviewSize(&width, &height);
-            ASSERT_TRUE((previewSizes[0].width == width) &&
-                    (previewSizes[0].height == height));
-
-            Return<void> ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -1852,39 +1996,50 @@
 // Verify that the static camera characteristics can be retrieved
 // successfully.
 TEST_F(CameraHidlTest, getCameraCharacteristics) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
-            Return<void> ret;
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("getCameraCharacteristics: Testing camera device %s",
+                      name.c_str());
+                Return<void> ret;
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            ret = device3_2->getCameraCharacteristics(
-                [&](auto status, const auto& chars) {
-                    ALOGI("getCameraCharacteristics returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    const camera_metadata_t* metadata = (camera_metadata_t*) chars.data();
-                    size_t expectedSize = chars.size();
-                    int result = validate_camera_metadata_structure(metadata, &expectedSize);
-                    ASSERT_TRUE(result == 0 || result == CAMERA_METADATA_VALIDATION_SHIFTED);
-                    size_t entryCount = get_camera_metadata_entry_count(metadata);
-                    // TODO: we can do better than 0 here. Need to check how many required
-                    // characteristics keys we've defined.
-                    ASSERT_GT(entryCount, 0u);
-                    ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount);
-                });
-            ASSERT_TRUE(ret.isOk());
+                ret = device3_2->getCameraCharacteristics(
+                    [&](auto status, const auto& chars) {
+                        ALOGI("getCameraCharacteristics returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        const camera_metadata_t* metadata =
+                                (camera_metadata_t*) chars.data();
+                        size_t expectedSize = chars.size();
+                        int result = validate_camera_metadata_structure(
+                                metadata, &expectedSize);
+                        ASSERT_TRUE((result == 0) ||
+                                (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+                        size_t entryCount = get_camera_metadata_entry_count(
+                                metadata);
+                        // TODO: we can do better than 0 here. Need to check how many required
+                        // characteristics keys we've defined.
+                        ASSERT_GT(entryCount, 0u);
+                        ALOGI("getCameraCharacteristics metadata entry count is %zu",
+                              entryCount);
+                    });
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -1892,252 +2047,273 @@
 //In case it is supported verify that torch can be enabled.
 //Check for corresponding toch callbacks as well.
 TEST_F(CameraHidlTest, setTorchMode) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    bool torchControlSupported = false;
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        bool torchControlSupported = false;
+        Return<void> ret;
 
-    ret = CameraHidlEnvironment::Instance()->mProvider->isSetTorchModeSupported(
-        [&](auto status, bool support) {
-            ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
-                    (int)status, support);
-            ASSERT_EQ(Status::OK, status);
-            torchControlSupported = support;
-        });
+        ret = provider.second->isSetTorchModeSupported(
+            [&](auto status, bool support) {
+                ALOGI("isSetTorchModeSupported returns status:%d supported:%d",
+                        (int)status, support);
+                ASSERT_EQ(Status::OK, status);
+                torchControlSupported = support;
+            });
 
 
-    sp<TorchProviderCb> cb = new TorchProviderCb(this);
-    Return<Status> returnStatus = env->mProvider->setCallback(cb);
-    ASSERT_TRUE(returnStatus.isOk());
-    ASSERT_EQ(Status::OK, returnStatus);
+        sp<TorchProviderCb> cb = new TorchProviderCb(this);
+        Return<Status> returnStatus = provider.second->setCallback(cb);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, returnStatus);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("setTorchMode: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("setTorchMode: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-            returnStatus = device3_2->setTorchMode(TorchMode::ON);
-            ASSERT_TRUE(returnStatus.isOk());
-            if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
-            } else {
-                ASSERT_TRUE(returnStatus == Status::OK ||
-                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
-                if (returnStatus == Status::OK) {
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device3_2->setTorchMode(TorchMode::ON);
+                ASSERT_TRUE(returnStatus.isOk());
+                if (!torchControlSupported) {
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_TRUE(returnStatus == Status::OK ||
+                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON,
+                                    mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
-                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-                    }
 
-                    returnStatus = device3_2->setTorchMode(TorchMode::OFF);
-                    ASSERT_TRUE(returnStatus.isOk());
-                    ASSERT_EQ(Status::OK, returnStatus);
+                        returnStatus = device3_2->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
 
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF,
+                                    mTorchStatus);
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
                     }
                 }
-            }
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-            returnStatus = device1->setTorchMode(TorchMode::ON);
-            ASSERT_TRUE(returnStatus.isOk());
-            if (!torchControlSupported) {
-                ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
-            } else {
-                ASSERT_TRUE(returnStatus == Status::OK ||
-                            returnStatus == Status::OPERATION_NOT_SUPPORTED);
-                if (returnStatus == Status::OK) {
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device1->setTorchMode(TorchMode::ON);
+                ASSERT_TRUE(returnStatus.isOk());
+                if (!torchControlSupported) {
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_TRUE(returnStatus == Status::OK ||
+                                returnStatus == Status::OPERATION_NOT_SUPPORTED);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON,
+                                    mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
-                        mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
-                    }
 
-                    returnStatus = device1->setTorchMode(TorchMode::OFF);
-                    ASSERT_TRUE(returnStatus.isOk());
-                    ASSERT_EQ(Status::OK, returnStatus);
+                        returnStatus = device1->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
 
-                    {
-                        std::unique_lock<std::mutex> l(mTorchLock);
-                        while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
-                            auto timeout = std::chrono::system_clock::now() +
-                                    std::chrono::seconds(kTorchTimeoutSec);
-                            ASSERT_NE(std::cv_status::timeout,
-                                    mTorchCond.wait_until(l, timeout));
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout,
+                                        mTorchCond.wait_until(l, timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF,
+                                    mTorchStatus);
                         }
-                        ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
                     }
                 }
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
         }
-    }
 
-    returnStatus = env->mProvider->setCallback(nullptr);
-    ASSERT_TRUE(returnStatus.isOk());
-    ASSERT_EQ(Status::OK, returnStatus);
+        returnStatus = provider.second->setCallback(nullptr);
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, returnStatus);
+    }
 }
 
 // Check dump functionality.
 TEST_F(CameraHidlTest, dumpState) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        Return<void> ret;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<ICameraDevice> device3_2;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            ret= device3_2->dumpState(handle);
-            ASSERT_TRUE(ret.isOk());
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            ALOGI("dumpState: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V1_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device1 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                ret= device3_2->dumpState(handle);
+                ASSERT_TRUE(ret.isOk());
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                ALOGI("dumpState: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V1_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device1 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            Return<Status> returnStatus = device1->dumpState(handle);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                Return<Status> returnStatus = device1->dumpState(handle);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
+            }
         }
     }
 }
 
 // Open, dumpStates, then close
 TEST_F(CameraHidlTest, openClose) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    Return<void> ret;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        Return<void> ret;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            ALOGI("openClose: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                ALOGI("openClose: Testing camera device %s", name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            ret = device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-            ASSERT_TRUE(ret.isOk());
+                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+                sp<ICameraDeviceSession> session;
+                ret = device3_2->open(
+                    cb,
+                    [&](auto status, const auto& newSession) {
+                        ALOGI("device::open returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(newSession, nullptr);
+                        session = newSession;
+                    });
+                ASSERT_TRUE(ret.isOk());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            ret = device3_2->dumpState(handle);
-            ASSERT_TRUE(ret.isOk());
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                ret = device3_2->dumpState(handle);
+                ASSERT_TRUE(ret.isOk());
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
-            // TODO: test all session API calls return INTERNAL_ERROR after close
-            // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
-        } else if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_1_0) {
-            sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
-            openCameraDevice(name, env, &device1 /*out*/);
-            ASSERT_NE(nullptr, device1.get());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+                // TODO: test all session API calls return INTERNAL_ERROR after close
+                // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
+            } else if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_1_0) {
+                sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
+                openCameraDevice(name, provider.second, &device1 /*out*/);
+                ASSERT_NE(nullptr, device1.get());
 
-            native_handle_t* raw_handle = native_handle_create(1, 0);
-            raw_handle->data[0] = open(kDumpOutput, O_RDWR);
-            ASSERT_GE(raw_handle->data[0], 0);
-            hidl_handle handle = raw_handle;
-            Return<Status> returnStatus = device1->dumpState(handle);
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
-            close(raw_handle->data[0]);
-            native_handle_delete(raw_handle);
+                native_handle_t* raw_handle = native_handle_create(1, 0);
+                raw_handle->data[0] = open(kDumpOutput, O_RDWR);
+                ASSERT_GE(raw_handle->data[0], 0);
+                hidl_handle handle = raw_handle;
+                Return<Status> returnStatus = device1->dumpState(handle);
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+                close(raw_handle->data[0]);
+                native_handle_delete(raw_handle);
 
-            ret = device1->close();
-            ASSERT_TRUE(ret.isOk());
+                ret = device1->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2145,71 +2321,81 @@
 // Check whether all common default request settings can be sucessfully
 // constructed.
 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
-            Return<void> ret;
-            ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
-            ret = env->mProvider->getCameraDeviceInterface_V3_x(
-                name,
-                [&](auto status, const auto& device) {
-                    ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(device, nullptr);
-                    device3_2 = device;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
-            sp<ICameraDeviceSession> session;
-            ret = device3_2->open(
-                cb,
-                [&](auto status, const auto& newSession) {
-                    ALOGI("device::open returns status:%d", (int)status);
-                    ASSERT_EQ(Status::OK, status);
-                    ASSERT_NE(newSession, nullptr);
-                    session = newSession;
-                });
-            ASSERT_TRUE(ret.isOk());
-
-            for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
-                    t <= (uint32_t) RequestTemplate::MANUAL; t++) {
-                RequestTemplate reqTemplate = (RequestTemplate) t;
-                ret = session->constructDefaultRequestSettings(
-                    reqTemplate,
-                    [&](auto status, const auto& req) {
-                        ALOGI("constructDefaultRequestSettings returns status:%d", (int)status);
-                        if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
-                                reqTemplate == RequestTemplate::MANUAL) {
-                            // optional templates
-                            ASSERT_TRUE(status == Status::OK || status == Status::ILLEGAL_ARGUMENT);
-                        } else {
-                            ASSERT_EQ(Status::OK, status);
-                        }
-
-                        if (status == Status::OK) {
-                            const camera_metadata_t* metadata =
-                                (camera_metadata_t*) req.data();
-                            size_t expectedSize = req.size();
-                            int result = validate_camera_metadata_structure(
-                                    metadata, &expectedSize);
-                            ASSERT_TRUE(result == 0 || result == CAMERA_METADATA_VALIDATION_SHIFTED);
-                            size_t entryCount = get_camera_metadata_entry_count(metadata);
-                            // TODO: we can do better than 0 here. Need to check how many required
-                            // request keys we've defined for each template
-                            ASSERT_GT(entryCount, 0u);
-                            ALOGI("template %u metadata entry count is %zu", t, entryCount);
-                        } else {
-                            ASSERT_EQ(0u, req.size());
-                        }
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2;
+                Return<void> ret;
+                ALOGI("constructDefaultRequestSettings: Testing camera device %s",
+                      name.c_str());
+                ret = provider.second->getCameraDeviceInterface_V3_x(
+                    name,
+                    [&](auto status, const auto& device) {
+                        ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
+                              (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(device, nullptr);
+                        device3_2 = device;
                     });
                 ASSERT_TRUE(ret.isOk());
+
+                sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
+                sp<ICameraDeviceSession> session;
+                ret = device3_2->open(
+                    cb,
+                    [&](auto status, const auto& newSession) {
+                        ALOGI("device::open returns status:%d", (int)status);
+                        ASSERT_EQ(Status::OK, status);
+                        ASSERT_NE(newSession, nullptr);
+                        session = newSession;
+                    });
+                ASSERT_TRUE(ret.isOk());
+
+                for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW;
+                        t <= (uint32_t) RequestTemplate::MANUAL; t++) {
+                    RequestTemplate reqTemplate = (RequestTemplate) t;
+                    ret = session->constructDefaultRequestSettings(
+                        reqTemplate,
+                        [&](auto status, const auto& req) {
+                            ALOGI("constructDefaultRequestSettings returns status:%d",
+                                  (int)status);
+                            if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
+                                    reqTemplate == RequestTemplate::MANUAL) {
+                                // optional templates
+                                ASSERT_TRUE((status == Status::OK) ||
+                                        (status == Status::ILLEGAL_ARGUMENT));
+                            } else {
+                                ASSERT_EQ(Status::OK, status);
+                            }
+
+                            if (status == Status::OK) {
+                                const camera_metadata_t* metadata =
+                                    (camera_metadata_t*) req.data();
+                                size_t expectedSize = req.size();
+                                int result = validate_camera_metadata_structure(
+                                        metadata, &expectedSize);
+                                ASSERT_TRUE((result == 0) ||
+                                        (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+                                size_t entryCount =
+                                        get_camera_metadata_entry_count(metadata);
+                                // TODO: we can do better than 0 here. Need to check how many required
+                                // request keys we've defined for each template
+                                ASSERT_GT(entryCount, 0u);
+                                ALOGI("template %u metadata entry count is %zu",
+                                      t, entryCount);
+                            } else {
+                                ASSERT_EQ(0u, req.size());
+                            }
+                        });
+                    ASSERT_TRUE(ret.isOk());
+                }
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
             }
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2217,104 +2403,94 @@
 // Verify that all supported stream formats and sizes can be configured
 // successfully.
 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputStreams;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputStreams;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputStreams));
-            ASSERT_NE(0u, outputStreams.size());
+                outputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputStreams));
+                ASSERT_NE(0u, outputStreams.size());
 
-            int32_t streamId = 0;
-            for (auto &it : outputStreams) {
-                Stream stream = {streamId, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (it.format), 0, 0,
-                        StreamRotation::ROTATION_0};
-                ::android::hardware::hidl_vec<Stream> streams = {stream};
-                StreamConfiguration config = {streams,
-                        StreamConfigurationMode::NORMAL_MODE};
-                ret = session->configureStreams(config, [streamId] (Status s,
-                        HalStreamConfiguration halConfig) {
-                    ASSERT_EQ(Status::OK, s);
-                    ASSERT_EQ(1u, halConfig.streams.size());
-                    ASSERT_EQ(halConfig.streams[0].id, streamId);
-                });
+                int32_t streamId = 0;
+                for (auto &it : outputStreams) {
+                    Stream stream = {streamId, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (it.format), 0, 0,
+                            StreamRotation::ROTATION_0};
+                    ::android::hardware::hidl_vec<Stream> streams = {stream};
+                    StreamConfiguration config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [streamId] (Status s,
+                            HalStreamConfiguration halConfig) {
+                        ASSERT_EQ(Status::OK, s);
+                        ASSERT_EQ(1u, halConfig.streams.size());
+                        ASSERT_EQ(halConfig.streams[0].id, streamId);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                    streamId++;
+                }
+
+                free_camera_metadata(staticMeta);
+                ret = session->close();
                 ASSERT_TRUE(ret.isOk());
-                streamId++;
             }
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Check for correct handling of invalid/incorrect configuration parameters.
 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputStreams;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputStreams;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputStreams));
-            ASSERT_NE(0u, outputStreams.size());
+                outputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputStreams));
+                ASSERT_NE(0u, outputStreams.size());
 
-            int32_t streamId = 0;
-            Stream stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (0),
-                    static_cast<uint32_t> (0),
-                    static_cast<PixelFormat> (outputStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {stream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            ret = session->configureStreams(config, [] (Status s,
-                    HalStreamConfiguration) {
-                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
-                            (Status::INTERNAL_ERROR == s));
-            });
-            ASSERT_TRUE(ret.isOk());
+                int32_t streamId = 0;
+                Stream stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (0),
+                        static_cast<uint32_t> (0),
+                        static_cast<PixelFormat> (outputStreams[0].format),
+                        0, 0, StreamRotation::ROTATION_0};
+                ::android::hardware::hidl_vec<Stream> streams = {stream};
+                StreamConfiguration config = {streams,
+                        StreamConfigurationMode::NORMAL_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                                (Status::INTERNAL_ERROR == s));
+                });
+                ASSERT_TRUE(ret.isOk());
 
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<PixelFormat> (outputStreams[0].format),
-                    0, 0, StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::NORMAL_MODE};
-            ret = session->configureStreams(config, [] (Status s,
-                    HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            for (auto &it : outputStreams) {
                 stream = {streamId++, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<PixelFormat> (outputStreams[0].format),
                         0, 0, StreamRotation::ROTATION_0};
                 streams[0] = stream;
                 config = {streams,
@@ -2325,24 +2501,40 @@
                 });
                 ASSERT_TRUE(ret.isOk());
 
-                stream = {streamId++, StreamType::OUTPUT,
-                        static_cast<uint32_t> (it.width),
-                        static_cast<uint32_t> (it.height),
-                        static_cast<PixelFormat> (it.format),
-                        0, 0, static_cast<StreamRotation> (UINT32_MAX)};
-                streams[0] = stream;
-                config = {streams,
-                        StreamConfigurationMode::NORMAL_MODE};
-                ret = session->configureStreams(config, [] (Status s,
-                        HalStreamConfiguration) {
-                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-                });
+                for (auto &it : outputStreams) {
+                    stream = {streamId++, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (UINT32_MAX),
+                            0, 0, StreamRotation::ROTATION_0};
+                    streams[0] = stream;
+                    config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [] (Status s,
+                            HalStreamConfiguration) {
+                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+
+                    stream = {streamId++, StreamType::OUTPUT,
+                            static_cast<uint32_t> (it.width),
+                            static_cast<uint32_t> (it.height),
+                            static_cast<PixelFormat> (it.format),
+                            0, 0, static_cast<StreamRotation> (UINT32_MAX)};
+                    streams[0] = stream;
+                    config = {streams,
+                            StreamConfigurationMode::NORMAL_MODE};
+                    ret = session->configureStreams(config, [] (Status s,
+                            HalStreamConfiguration) {
+                        ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                    });
+                    ASSERT_TRUE(ret.isOk());
+                }
+
+                free_camera_metadata(staticMeta);
+                ret = session->close();
                 ASSERT_TRUE(ret.isOk());
             }
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2350,83 +2542,86 @@
 // Check whether all supported ZSL output stream combinations can be
 // configured successfully.
 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> inputStreams;
-    std::vector<AvailableZSLInputOutput> inputOutputMap;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> inputStreams;
+        std::vector<AvailableZSLInputOutput> inputOutputMap;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            Status rc = isZSLModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == rc) {
-                ret = session->close();
-                ASSERT_TRUE(ret.isOk());
-                continue;
-            }
-            ASSERT_EQ(Status::OK, rc);
+                Status rc = isZSLModeAvailable(staticMeta);
+                if (Status::METHOD_NOT_SUPPORTED == rc) {
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+                ASSERT_EQ(Status::OK, rc);
 
-            inputStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    inputStreams));
-            ASSERT_NE(0u, inputStreams.size());
-
-            inputOutputMap.clear();
-            ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
-                    inputOutputMap));
-            ASSERT_NE(0u, inputOutputMap.size());
-
-            int32_t streamId = 0;
-            for (auto &inputIter : inputOutputMap) {
-                AvailableStream input;
-                ASSERT_EQ(Status::OK,
-                        findLargestSize(inputStreams, inputIter.inputFormat, input));
+                inputStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        inputStreams));
                 ASSERT_NE(0u, inputStreams.size());
 
-                AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
-                        inputIter.outputFormat};
-                std::vector<AvailableStream> outputStreams;
-                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                        outputStreams, &outputThreshold));
-                for (auto &outputIter : outputStreams) {
-                    Stream zslStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (input.width),
-                            static_cast<uint32_t> (input.height),
-                            static_cast<PixelFormat> (input.format),
-                            GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream inputStream = {streamId++, StreamType::INPUT,
-                            static_cast<uint32_t> (input.width),
-                            static_cast<uint32_t> (input.height),
-                            static_cast<PixelFormat> (input.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream outputStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (outputIter.width),
-                            static_cast<uint32_t> (outputIter.height),
-                            static_cast<PixelFormat> (outputIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
+                inputOutputMap.clear();
+                ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta,
+                        inputOutputMap));
+                ASSERT_NE(0u, inputOutputMap.size());
 
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            inputStream, zslStream, outputStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                int32_t streamId = 0;
+                for (auto &inputIter : inputOutputMap) {
+                    AvailableStream input;
+                    ASSERT_EQ(Status::OK,
+                            findLargestSize(inputStreams, inputIter.inputFormat, input));
+                    ASSERT_NE(0u, inputStreams.size());
+
+                    AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
+                            inputIter.outputFormat};
+                    std::vector<AvailableStream> outputStreams;
+                    ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                            outputStreams, &outputThreshold));
+                    for (auto &outputIter : outputStreams) {
+                        Stream zslStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (input.width),
+                                static_cast<uint32_t> (input.height),
+                                static_cast<PixelFormat> (input.format),
+                                GRALLOC_USAGE_HW_CAMERA_ZSL, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream inputStream = {streamId++, StreamType::INPUT,
+                                static_cast<uint32_t> (input.width),
+                                static_cast<uint32_t> (input.height),
+                                static_cast<PixelFormat> (input.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream outputStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (outputIter.width),
+                                static_cast<uint32_t> (outputIter.height),
+                                static_cast<PixelFormat> (outputIter.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                inputStream, zslStream, outputStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(3u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2434,62 +2629,65 @@
 // Verify that all supported preview + still capture stream combinations
 // can be configured successfully.
 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
-            static_cast<int32_t>(PixelFormat::BLOB)};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
+                static_cast<int32_t>(PixelFormat::BLOB)};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
+                outputBlobStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputBlobStreams, &blobThreshold));
+                ASSERT_NE(0u, outputBlobStreams.size());
 
-            outputPreviewStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputPreviewStreams, &previewThreshold));
-            ASSERT_NE(0u, outputPreviewStreams.size());
+                outputPreviewStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputPreviewStreams, &previewThreshold));
+                ASSERT_NE(0u, outputPreviewStreams.size());
 
-            int32_t streamId = 0;
-            for (auto &blobIter : outputBlobStreams) {
-                for (auto &previewIter : outputPreviewStreams) {
-                    Stream previewStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (previewIter.width),
-                            static_cast<uint32_t> (previewIter.height),
-                            static_cast<PixelFormat> (previewIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream blobStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (blobIter.width),
-                            static_cast<uint32_t> (blobIter.height),
-                            static_cast<PixelFormat> (blobIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            previewStream, blobStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                int32_t streamId = 0;
+                for (auto &blobIter : outputBlobStreams) {
+                    for (auto &previewIter : outputPreviewStreams) {
+                        Stream previewStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (previewIter.width),
+                                static_cast<uint32_t> (previewIter.height),
+                                static_cast<PixelFormat> (previewIter.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        Stream blobStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (blobIter.width),
+                                static_cast<uint32_t> (blobIter.height),
+                                static_cast<PixelFormat> (blobIter.format), 0, 0,
+                                StreamRotation::ROTATION_0};
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                previewStream, blobStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(2u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2498,89 +2696,95 @@
 // configured. Additionally check for common invalid inputs when
 // using this mode.
 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            Status rc = isConstrainedModeAvailable(staticMeta);
-            if (Status::METHOD_NOT_SUPPORTED == rc) {
+                Status rc = isConstrainedModeAvailable(staticMeta);
+                if (Status::METHOD_NOT_SUPPORTED == rc) {
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
+                    continue;
+                }
+                ASSERT_EQ(Status::OK, rc);
+
+                AvailableStream hfrStream;
+                rc = pickConstrainedModeSize(staticMeta, hfrStream);
+                ASSERT_EQ(Status::OK, rc);
+
+                int32_t streamId = 0;
+                Stream stream = {streamId, StreamType::OUTPUT,
+                        static_cast<uint32_t> (hfrStream.width),
+                        static_cast<uint32_t> (hfrStream.height),
+                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        StreamRotation::ROTATION_0};
+                ::android::hardware::hidl_vec<Stream> streams = {stream};
+                StreamConfiguration config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [streamId] (Status s,
+                        HalStreamConfiguration halConfig) {
+                    ASSERT_EQ(Status::OK, s);
+                    ASSERT_EQ(1u, halConfig.streams.size());
+                    ASSERT_EQ(halConfig.streams[0].id, streamId);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (0),
+                        static_cast<uint32_t> (0),
+                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
+                                (Status::INTERNAL_ERROR == s));
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<uint32_t> (UINT32_MAX),
+                        static_cast<PixelFormat> (hfrStream.format), 0, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                stream = {streamId++, StreamType::OUTPUT,
+                        static_cast<uint32_t> (hfrStream.width),
+                        static_cast<uint32_t> (hfrStream.height),
+                        static_cast<PixelFormat> (UINT32_MAX), 0, 0,
+                        StreamRotation::ROTATION_0};
+                streams[0] = stream;
+                config = {streams,
+                        StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
+                ret = session->configureStreams(config, [] (Status s,
+                        HalStreamConfiguration) {
+                    ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
+                });
+                ASSERT_TRUE(ret.isOk());
+
+                free_camera_metadata(staticMeta);
                 ret = session->close();
                 ASSERT_TRUE(ret.isOk());
-                continue;
             }
-            ASSERT_EQ(Status::OK, rc);
-
-            AvailableStream hfrStream;
-            rc = pickConstrainedModeSize(staticMeta, hfrStream);
-            ASSERT_EQ(Status::OK, rc);
-
-            int32_t streamId = 0;
-            Stream stream = {streamId, StreamType::OUTPUT,
-                    static_cast<uint32_t> (hfrStream.width),
-                    static_cast<uint32_t> (hfrStream.height),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            ::android::hardware::hidl_vec<Stream> streams = {stream};
-            StreamConfiguration config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [streamId] (Status s,
-                    HalStreamConfiguration halConfig) {
-                ASSERT_EQ(Status::OK, s);
-                ASSERT_EQ(1u, halConfig.streams.size());
-                ASSERT_EQ(halConfig.streams[0].id, streamId);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (0),
-                    static_cast<uint32_t> (0),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
-                            (Status::INTERNAL_ERROR == s));
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<uint32_t> (UINT32_MAX),
-                    static_cast<PixelFormat> (hfrStream.format), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            stream = {streamId++, StreamType::OUTPUT,
-                    static_cast<uint32_t> (hfrStream.width),
-                    static_cast<uint32_t> (hfrStream.height),
-                    static_cast<PixelFormat> (UINT32_MAX), 0, 0,
-                    StreamRotation::ROTATION_0};
-            streams[0] = stream;
-            config = {streams,
-                    StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE};
-            ret = session->configureStreams(config, [](Status s, HalStreamConfiguration) {
-                ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
-            });
-            ASSERT_TRUE(ret.isOk());
-
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2588,209 +2792,215 @@
 // Verify that all supported video + snapshot stream combinations can
 // be configured successfully.
 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    std::vector<AvailableStream> outputVideoStreams;
-    AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
-            static_cast<int32_t>(PixelFormat::BLOB)};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        std::vector<AvailableStream> outputVideoStreams;
+        AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
+                static_cast<int32_t>(PixelFormat::BLOB)};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_t *staticMeta;
-            Return<void> ret;
-            sp<ICameraDeviceSession> session;
-            openEmptyDeviceSession(name, env, &session /*out*/,
-                    &staticMeta /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                camera_metadata_t *staticMeta;
+                Return<void> ret;
+                sp<ICameraDeviceSession> session;
+                openEmptyDeviceSession(name, provider.second, &session /*out*/,
+                        &staticMeta /*out*/);
 
-            outputBlobStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputBlobStreams, &blobThreshold));
-            ASSERT_NE(0u, outputBlobStreams.size());
+                outputBlobStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputBlobStreams, &blobThreshold));
+                ASSERT_NE(0u, outputBlobStreams.size());
 
-            outputVideoStreams.clear();
-            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
-                    outputVideoStreams, &videoThreshold));
-            ASSERT_NE(0u, outputVideoStreams.size());
+                outputVideoStreams.clear();
+                ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta,
+                        outputVideoStreams, &videoThreshold));
+                ASSERT_NE(0u, outputVideoStreams.size());
 
-            int32_t streamId = 0;
-            for (auto &blobIter : outputBlobStreams) {
-                for (auto &videoIter : outputVideoStreams) {
-                    Stream videoStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (videoIter.width),
-                            static_cast<uint32_t> (videoIter.height),
-                            static_cast<PixelFormat> (videoIter.format), 0, 0,
-                            StreamRotation::ROTATION_0};
-                    Stream blobStream = {streamId++, StreamType::OUTPUT,
-                            static_cast<uint32_t> (blobIter.width),
-                            static_cast<uint32_t> (blobIter.height),
-                            static_cast<PixelFormat> (blobIter.format),
-                            GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
-                            StreamRotation::ROTATION_0};
-                    ::android::hardware::hidl_vec<Stream> streams = {
-                            videoStream, blobStream};
-                    StreamConfiguration config = {streams,
-                            StreamConfigurationMode::NORMAL_MODE};
-                    ret = session->configureStreams(config,
+                int32_t streamId = 0;
+                for (auto &blobIter : outputBlobStreams) {
+                    for (auto &videoIter : outputVideoStreams) {
+                        Stream videoStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (videoIter.width),
+                                static_cast<uint32_t> (videoIter.height),
+                                static_cast<PixelFormat> (videoIter.format),
+                                0, 0, StreamRotation::ROTATION_0};
+                        Stream blobStream = {streamId++, StreamType::OUTPUT,
+                                static_cast<uint32_t> (blobIter.width),
+                                static_cast<uint32_t> (blobIter.height),
+                                static_cast<PixelFormat> (blobIter.format),
+                                GRALLOC_USAGE_HW_VIDEO_ENCODER, 0,
+                                StreamRotation::ROTATION_0};
+                        ::android::hardware::hidl_vec<Stream> streams = {
+                                videoStream, blobStream};
+                        StreamConfiguration config = {streams,
+                                StreamConfigurationMode::NORMAL_MODE};
+                        ret = session->configureStreams(config,
                                                     [](Status s, HalStreamConfiguration halConfig) {
                                                         ASSERT_EQ(Status::OK, s);
                                                         ASSERT_EQ(2u, halConfig.streams.size());
                                                     });
-                    ASSERT_TRUE(ret.isOk());
+                        ASSERT_TRUE(ret.isOk());
+                    }
                 }
-            }
 
-            free_camera_metadata(staticMeta);
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                free_camera_metadata(staticMeta);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Generate and verify a camera capture request
 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            bool supportsPartialResults = false;
-            uint32_t partialResultCount = 0;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
-                    &partialResultCount/*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount/*out*/);
 
-            std::shared_ptr<ResultMetadataQueue> resultQueue;
-            auto resultQueueRet = session->getCaptureResultMetadataQueue(
-                [&resultQueue](const auto& descriptor) {
-                    resultQueue = std::make_shared<ResultMetadataQueue>(
-                            descriptor);
-                    if (!resultQueue->isValid() ||
-                            resultQueue->availableToWrite() <= 0) {
-                        ALOGE("%s: HAL returns empty result metadata fmq,"
-                                " not use it", __func__);
-                        resultQueue = nullptr;
-                        // Don't use the queue onwards.
+                std::shared_ptr<ResultMetadataQueue> resultQueue;
+                auto resultQueueRet = session->getCaptureResultMetadataQueue(
+                    [&resultQueue](const auto& descriptor) {
+                        resultQueue = std::make_shared<ResultMetadataQueue>(
+                                descriptor);
+                        if (!resultQueue->isValid() ||
+                                resultQueue->availableToWrite() <= 0) {
+                            ALOGE("%s: HAL returns empty result metadata fmq,"
+                                    " not use it", __func__);
+                            resultQueue = nullptr;
+                            // Don't use the queue onwards.
+                        }
+                    });
+                ASSERT_TRUE(resultQueueRet.isOk());
+                ASSERT_NE(nullptr, resultQueue);
+
+                InFlightRequest inflightReq = {1, false, supportsPartialResults,
+                        partialResultCount, resultQueue};
+
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
+
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+                ASSERT_NE(nullptr, gb.get());
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */,
+                        settings, emptyInputBuffer, outputBuffers};
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap.clear();
+                    mInflightMap.add(frameNumber, &inflightReq);
+                }
+
+                Status status = Status::INTERNAL_ERROR;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                Return<void> returnStatus = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
                     }
-                });
-            ASSERT_TRUE(resultQueueRet.isOk());
-            ASSERT_NE(nullptr, resultQueue);
 
-            InFlightRequest inflightReq = {1, false, supportsPartialResults,
-                    partialResultCount, resultQueue};
+                    ASSERT_FALSE(inflightReq.errorCodeValid);
+                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                    ASSERT_EQ(previewStream.id,
+                              inflightReq.resultOutputBuffers[0].streamId);
 
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-            ASSERT_NE(nullptr, gb.get());
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mInflightMap.clear();
-                mInflightMap.add(frameNumber, &inflightReq);
-            }
-
-            Status status = Status::INTERNAL_ERROR;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            Return<void> returnStatus = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (!inflightReq.errorCodeValid &&
-                        ((0 < inflightReq.numBuffersLeft) ||
-                                (!inflightReq.haveResultMetadata))) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                    request.frameNumber++;
+                    //Empty settings should be supported after the first call
+                    //for repeating requests.
+                    request.settings.setToExternal(nullptr, 0, true);
+                    mInflightMap.clear();
+                    inflightReq = {1, false, supportsPartialResults,
+                                        partialResultCount, resultQueue};
+                    mInflightMap.add(request.frameNumber, &inflightReq);
                 }
 
-                ASSERT_FALSE(inflightReq.errorCodeValid);
-                ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
-                ASSERT_EQ(previewStream.id,
-                          inflightReq.resultOutputBuffers[0].streamId);
+                returnStatus = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
 
-                request.frameNumber++;
-                //Empty settings should be supported after the first call
-                //for repeating requests.
-                request.settings.setToExternal(nullptr, 0, true);
-                mInflightMap.clear();
-                inflightReq = {1, false, supportsPartialResults,
-                                    partialResultCount, resultQueue};
-                mInflightMap.add(request.frameNumber, &inflightReq);
-            }
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
+                    }
 
-            returnStatus = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (!inflightReq.errorCodeValid &&
-                        ((0 < inflightReq.numBuffersLeft) ||
-                                (!inflightReq.haveResultMetadata))) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                    ASSERT_FALSE(inflightReq.errorCodeValid);
+                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                    ASSERT_EQ(previewStream.id,
+                              inflightReq.resultOutputBuffers[0].streamId);
                 }
 
-                ASSERT_FALSE(inflightReq.errorCodeValid);
-                ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
-                ASSERT_EQ(previewStream.id,
-                          inflightReq.resultOutputBuffers[0].streamId);
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
             }
-
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -2798,61 +3008,64 @@
 // Test whether an incorrect capture request with missing settings will
 // be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            bool supportsPartialResults = false;
-            uint32_t partialResultCount = 0;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
-                    &partialResultCount /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
 
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
 
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
+                        emptyInputBuffer, outputBuffers};
 
-            //Settings were not correctly initialized, we should fail here
-            Status status = Status::OK;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            Return<void> ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::INTERNAL_ERROR, status);
-            ASSERT_EQ(numRequestProcessed, 0u);
+                //Settings were not correctly initialized, we should fail here
+                Status status = Status::OK;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                Return<void> ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::INTERNAL_ERROR, status);
+                ASSERT_EQ(numRequestProcessed, 0u);
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
@@ -2860,222 +3073,231 @@
 // Check whether an invalid capture request with missing output buffers
 // will be reported correctly.
 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputBlobStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputBlobStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            bool supportsPartialResults = false;
-            uint32_t partialResultCount = 0;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/, &supportsPartialResults/*out*/,
-                    &partialResultCount /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults/*out*/,
+                        &partialResultCount /*out*/);
 
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
 
-            ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
-            StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, settings,
-                    emptyInputBuffer, emptyOutputBuffers};
+                ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
+                StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */,
+                        settings, emptyInputBuffer, emptyOutputBuffers};
 
-            //Output buffers are missing, we should fail here
-            Status status = Status::OK;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
-                    });
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::INTERNAL_ERROR, status);
-            ASSERT_EQ(numRequestProcessed, 0u);
+                //Output buffers are missing, we should fail here
+                Status status = Status::OK;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::INTERNAL_ERROR, status);
+                ASSERT_EQ(numRequestProcessed, 0u);
 
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
+                ret = session->close();
+                ASSERT_TRUE(ret.isOk());
+            }
         }
     }
 }
 
 // Generate, trigger and flush a preview request
 TEST_F(CameraHidlTest, flushPreviewRequest) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
-    uint64_t bufferId = 1;
-    uint32_t frameNumber = 1;
-    ::android::hardware::hidl_vec<uint8_t> settings;
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+        uint64_t bufferId = 1;
+        uint32_t frameNumber = 1;
+        ::android::hardware::hidl_vec<uint8_t> settings;
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            bool supportsPartialResults = false;
-            uint32_t partialResultCount = 0;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
-                    &partialResultCount /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
 
-            std::shared_ptr<ResultMetadataQueue> resultQueue;
-            auto resultQueueRet = session->getCaptureResultMetadataQueue(
-                [&resultQueue](const auto& descriptor) {
-                    resultQueue = std::make_shared<ResultMetadataQueue>(
-                            descriptor);
-                    if (!resultQueue->isValid() ||
-                            resultQueue->availableToWrite() <= 0) {
-                        ALOGE("%s: HAL returns empty result metadata fmq,"
-                                " not use it", __func__);
-                        resultQueue = nullptr;
-                        // Don't use the queue onwards.
-                    }
-                });
-            ASSERT_TRUE(resultQueueRet.isOk());
-            ASSERT_NE(nullptr, resultQueue);
-
-            InFlightRequest inflightReq = {1, false, supportsPartialResults,
-                    partialResultCount, resultQueue};
-            RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
-            Return<void> ret;
-            ret = session->constructDefaultRequestSettings(reqTemplate,
-                [&](auto status, const auto& req) {
-                    ASSERT_EQ(Status::OK, status);
-                    settings = req; });
-            ASSERT_TRUE(ret.isOk());
-
-            sp<GraphicBuffer> gb = new GraphicBuffer(
-                previewStream.width, previewStream.height,
-                static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
-                1, android_convertGralloc1To0Usage(
-                       halStreamConfig.streams[0].producerUsage,
-                       halStreamConfig.streams[0].consumerUsage));
-            ASSERT_NE(nullptr, gb.get());
-            StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
-                    bufferId, hidl_handle(gb->getNativeBuffer()->handle),
-                    BufferStatus::OK, nullptr, nullptr};
-            ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
-                    outputBuffer};
-            const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
-                    BufferStatus::ERROR, nullptr, nullptr};
-            CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
-                    emptyInputBuffer, outputBuffers};
-
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mInflightMap.clear();
-                mInflightMap.add(frameNumber, &inflightReq);
-            }
-
-            Status status = Status::INTERNAL_ERROR;
-            uint32_t numRequestProcessed = 0;
-            hidl_vec<BufferCache> cachesToRemove;
-            ret = session->processCaptureRequest(
-                    {request},
-                    cachesToRemove,
-                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
-                        status = s;
-                        numRequestProcessed = n;
+                std::shared_ptr<ResultMetadataQueue> resultQueue;
+                auto resultQueueRet = session->getCaptureResultMetadataQueue(
+                    [&resultQueue](const auto& descriptor) {
+                        resultQueue = std::make_shared<ResultMetadataQueue>(
+                                descriptor);
+                        if (!resultQueue->isValid() ||
+                                resultQueue->availableToWrite() <= 0) {
+                            ALOGE("%s: HAL returns empty result metadata fmq,"
+                                    " not use it", __func__);
+                            resultQueue = nullptr;
+                            // Don't use the queue onwards.
+                        }
                     });
+                ASSERT_TRUE(resultQueueRet.isOk());
+                ASSERT_NE(nullptr, resultQueue);
 
-            ASSERT_TRUE(ret.isOk());
-            ASSERT_EQ(Status::OK, status);
-            ASSERT_EQ(numRequestProcessed, 1u);
-            //Flush before waiting for request to complete.
-            Return<Status> returnStatus = session->flush();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                InFlightRequest inflightReq = {1, false, supportsPartialResults,
+                        partialResultCount, resultQueue};
+                RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
+                Return<void> ret;
+                ret = session->constructDefaultRequestSettings(reqTemplate,
+                    [&](auto status, const auto& req) {
+                        ASSERT_EQ(Status::OK, status);
+                        settings = req; });
+                ASSERT_TRUE(ret.isOk());
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                while (!inflightReq.errorCodeValid &&
-                        ((0 < inflightReq.numBuffersLeft) ||
-                                (!inflightReq.haveResultMetadata))) {
-                    auto timeout = std::chrono::system_clock::now() +
-                            std::chrono::seconds(kStreamBufferTimeoutSec);
-                    ASSERT_NE(std::cv_status::timeout,
-                            mResultCondition.wait_until(l, timeout));
+                sp<GraphicBuffer> gb = new GraphicBuffer(
+                    previewStream.width, previewStream.height,
+                    static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat),
+                    1, android_convertGralloc1To0Usage(
+                           halStreamConfig.streams[0].producerUsage,
+                           halStreamConfig.streams[0].consumerUsage));
+                ASSERT_NE(nullptr, gb.get());
+                StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
+                        bufferId, hidl_handle(gb->getNativeBuffer()->handle),
+                        BufferStatus::OK, nullptr, nullptr};
+                ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {
+                        outputBuffer};
+                const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
+                        BufferStatus::ERROR, nullptr, nullptr};
+                CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */,
+                        settings, emptyInputBuffer, outputBuffers};
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap.clear();
+                    mInflightMap.add(frameNumber, &inflightReq);
                 }
 
-                if (!inflightReq.errorCodeValid) {
-                    ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
-                    ASSERT_EQ(previewStream.id,
-                              inflightReq.resultOutputBuffers[0].streamId);
-                } else {
-                    switch (inflightReq.errorCode) {
-                        case ErrorCode::ERROR_REQUEST:
-                        case ErrorCode::ERROR_RESULT:
-                        case ErrorCode::ERROR_BUFFER:
-                            //Expected
-                            break;
-                        case ErrorCode::ERROR_DEVICE:
-                        default:
-                            FAIL() << "Unexpected error:" << static_cast<uint32_t> (
-                                    inflightReq.errorCode);
+                Status status = Status::INTERNAL_ERROR;
+                uint32_t numRequestProcessed = 0;
+                hidl_vec<BufferCache> cachesToRemove;
+                ret = session->processCaptureRequest(
+                        {request},
+                        cachesToRemove,
+                        [&status, &numRequestProcessed] (auto s, uint32_t n) {
+                            status = s;
+                            numRequestProcessed = n;
+                        });
+
+                ASSERT_TRUE(ret.isOk());
+                ASSERT_EQ(Status::OK, status);
+                ASSERT_EQ(numRequestProcessed, 1u);
+                //Flush before waiting for request to complete.
+                Return<Status> returnStatus = session->flush();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
+
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    while (!inflightReq.errorCodeValid &&
+                            ((0 < inflightReq.numBuffersLeft) ||
+                                    (!inflightReq.haveResultMetadata))) {
+                        auto timeout = std::chrono::system_clock::now() +
+                                std::chrono::seconds(kStreamBufferTimeoutSec);
+                        ASSERT_NE(std::cv_status::timeout,
+                                mResultCondition.wait_until(l, timeout));
                     }
+
+                    if (!inflightReq.errorCodeValid) {
+                        ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+                        ASSERT_EQ(previewStream.id,
+                                  inflightReq.resultOutputBuffers[0].streamId);
+                    } else {
+                        switch (inflightReq.errorCode) {
+                            case ErrorCode::ERROR_REQUEST:
+                            case ErrorCode::ERROR_RESULT:
+                            case ErrorCode::ERROR_BUFFER:
+                                //Expected
+                                break;
+                            case ErrorCode::ERROR_DEVICE:
+                            default:
+                                FAIL() << "Unexpected error:" << static_cast<uint32_t> (
+                                        inflightReq.errorCode);
+                        }
+                    }
+
+                    ret = session->close();
+                    ASSERT_TRUE(ret.isOk());
                 }
             }
-
-            ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
 
 // Verify that camera flushes correctly without any pending requests.
 TEST_F(CameraHidlTest, flushEmpty) {
-    CameraHidlEnvironment* env = CameraHidlEnvironment::Instance();
-    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames();
-    std::vector<AvailableStream> outputPreviewStreams;
-    AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
-            static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    for (auto provider : CameraHidlEnvironment::Instance()->mProviders) {
+        hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(
+                provider.second);
+        std::vector<AvailableStream> outputPreviewStreams;
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
 
-    for (const auto& name : cameraDeviceNames) {
-        if (getCameraDeviceVersion(name) == CAMERA_DEVICE_API_VERSION_3_2) {
-            Stream previewStream;
-            HalStreamConfiguration halStreamConfig;
-            sp<ICameraDeviceSession> session;
-            bool supportsPartialResults = false;
-            uint32_t partialResultCount = 0;
-            configurePreviewStream(name, env, &previewThreshold,
-                    &session /*out*/, &previewStream /*out*/,
-                    &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
-                    &partialResultCount /*out*/);
+        for (const auto& name : cameraDeviceNames) {
+            if (getCameraDeviceVersion(name, provider.first) ==
+                    CAMERA_DEVICE_API_VERSION_3_2) {
+                Stream previewStream;
+                HalStreamConfiguration halStreamConfig;
+                sp<ICameraDeviceSession> session;
+                bool supportsPartialResults = false;
+                uint32_t partialResultCount = 0;
+                configurePreviewStream(name, provider.second, &previewThreshold,
+                        &session /*out*/, &previewStream /*out*/,
+                        &halStreamConfig /*out*/, &supportsPartialResults /*out*/,
+                        &partialResultCount /*out*/);
 
-            Return<Status> returnStatus = session->flush();
-            ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(Status::OK, returnStatus);
+                Return<Status> returnStatus = session->flush();
+                ASSERT_TRUE(returnStatus.isOk());
+                ASSERT_EQ(Status::OK, returnStatus);
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                auto timeout = std::chrono::system_clock::now() +
-                        std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
-                ASSERT_EQ(std::cv_status::timeout,
-                        mResultCondition.wait_until(l, timeout));
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    auto timeout = std::chrono::system_clock::now() +
+                            std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
+                    ASSERT_EQ(std::cv_status::timeout,
+                            mResultCondition.wait_until(l, timeout));
+                }
+
+                Return<void> ret = session->close();
+                ASSERT_TRUE(ret.isOk());
             }
-
-            Return<void> ret = session->close();
-            ASSERT_TRUE(ret.isOk());
         }
     }
 }
@@ -3265,14 +3487,13 @@
 
 // Open a device session and configure a preview stream.
 void CameraHidlTest::configurePreviewStream(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         const AvailableStream *previewThreshold,
         sp<ICameraDeviceSession> *session /*out*/,
         Stream *previewStream /*out*/,
         HalStreamConfiguration *halStreamConfig /*out*/,
         bool *supportsPartialResults /*out*/,
         uint32_t *partialResultCount /*out*/) {
-    ASSERT_NE(nullptr, env);
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, previewStream);
     ASSERT_NE(nullptr, halStreamConfig);
@@ -3283,7 +3504,7 @@
     ::android::sp<ICameraDevice> device3_2;
     ALOGI("configureStreams: Testing camera device %s", name.c_str());
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+    ret = provider->getCameraDeviceInterface_V3_x(
         name,
         [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
@@ -3349,17 +3570,16 @@
 
 // Open a device session with empty callbacks and return static metadata.
 void CameraHidlTest::openEmptyDeviceSession(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         sp<ICameraDeviceSession> *session /*out*/,
         camera_metadata_t **staticMeta /*out*/) {
-    ASSERT_NE(nullptr, env);
     ASSERT_NE(nullptr, session);
     ASSERT_NE(nullptr, staticMeta);
 
     ::android::sp<ICameraDevice> device3_2;
     ALOGI("configureStreams: Testing camera device %s", name.c_str());
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V3_x(
+    ret = provider->getCameraDeviceInterface_V3_x(
         name,
         [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
@@ -3391,13 +3611,12 @@
 
 // Open a particular camera device.
 void CameraHidlTest::openCameraDevice(const std::string &name,
-        const CameraHidlEnvironment* env,
+        sp<ICameraProvider> provider,
         sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
-    ASSERT_TRUE(nullptr != env);
     ASSERT_TRUE(nullptr != device1);
 
     Return<void> ret;
-    ret = env->mProvider->getCameraDeviceInterface_V1_x(
+    ret = provider->getCameraDeviceInterface_V1_x(
             name,
             [&](auto status, const auto& device) {
             ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
