/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "FrameHandler.h"
#include "FrameHandlerUltrasonics.h"

#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/automotive/evs/BnEvsEnumeratorStatusCallback.h>
#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
#include <aidl/android/hardware/automotive/evs/CameraParam.h>
#include <aidl/android/hardware/automotive/evs/DeviceStatus.h>
#include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
#include <aidl/android/hardware/automotive/evs/DisplayState.h>
#include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
#include <aidl/android/hardware/automotive/evs/EvsEventType.h>
#include <aidl/android/hardware/automotive/evs/EvsResult.h>
#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
#include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
#include <aidl/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.h>
#include <aidl/android/hardware/automotive/evs/IEvsUltrasonicsArray.h>
#include <aidl/android/hardware/automotive/evs/ParameterRange.h>
#include <aidl/android/hardware/automotive/evs/Stream.h>
#include <aidl/android/hardware/automotive/evs/UltrasonicsArrayDesc.h>
#include <aidl/android/hardware/common/NativeHandle.h>
#include <aidl/android/hardware/graphics/common/HardwareBufferDescription.h>
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <aidlcommonsupport/NativeHandle.h>
#include <android-base/logging.h>
#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/binder_status.h>
#include <system/camera_metadata.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>
#include <utils/Timers.h>

#include <chrono>
#include <deque>
#include <thread>
#include <unordered_set>

namespace {

// These values are called out in the EVS design doc (as of Mar 8, 2017)
constexpr int kMaxStreamStartMilliseconds = 500;
constexpr int kMinimumFramesPerSecond = 10;
constexpr int kSecondsToMilliseconds = 1000;
constexpr int kMillisecondsToMicroseconds = 1000;
constexpr float kNanoToMilliseconds = 0.000001f;
constexpr float kNanoToSeconds = 0.000000001f;

/*
 * Please note that this is different from what is defined in
 * libhardware/modules/camera/3_4/metadata/types.h; this has one additional
 * field to store a framerate.
 */
typedef struct {
    int32_t id;
    int32_t width;
    int32_t height;
    int32_t format;
    int32_t direction;
    int32_t framerate;
} RawStreamConfig;
constexpr size_t kStreamCfgSz = sizeof(RawStreamConfig) / sizeof(int32_t);

using ::aidl::android::hardware::automotive::evs::BnEvsEnumeratorStatusCallback;
using ::aidl::android::hardware::automotive::evs::BufferDesc;
using ::aidl::android::hardware::automotive::evs::CameraDesc;
using ::aidl::android::hardware::automotive::evs::CameraParam;
using ::aidl::android::hardware::automotive::evs::DeviceStatus;
using ::aidl::android::hardware::automotive::evs::DisplayDesc;
using ::aidl::android::hardware::automotive::evs::DisplayState;
using ::aidl::android::hardware::automotive::evs::EvsEventDesc;
using ::aidl::android::hardware::automotive::evs::EvsEventType;
using ::aidl::android::hardware::automotive::evs::EvsResult;
using ::aidl::android::hardware::automotive::evs::IEvsCamera;
using ::aidl::android::hardware::automotive::evs::IEvsDisplay;
using ::aidl::android::hardware::automotive::evs::IEvsEnumerator;
using ::aidl::android::hardware::automotive::evs::IEvsEnumeratorStatusCallback;
using ::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray;
using ::aidl::android::hardware::automotive::evs::ParameterRange;
using ::aidl::android::hardware::automotive::evs::Stream;
using ::aidl::android::hardware::automotive::evs::UltrasonicsArrayDesc;
using ::aidl::android::hardware::graphics::common::BufferUsage;
using ::aidl::android::hardware::graphics::common::HardwareBufferDescription;
using ::aidl::android::hardware::graphics::common::PixelFormat;
using std::chrono_literals::operator""s;

}  // namespace

// The main test class for EVS
class EvsAidlTest : public ::testing::TestWithParam<std::string> {
  public:
    virtual void SetUp() override {
        // Make sure we can connect to the enumerator
        std::string service_name = GetParam();
        AIBinder* binder = AServiceManager_waitForService(service_name.data());
        ASSERT_NE(binder, nullptr);
        mEnumerator = IEvsEnumerator::fromBinder(::ndk::SpAIBinder(binder));
        LOG(INFO) << "Test target service: " << service_name;

        ASSERT_TRUE(mEnumerator->isHardware(&mIsHwModule).isOk());
    }

    virtual void TearDown() override {
        // Attempt to close any active camera
        for (auto&& cam : mActiveCameras) {
            if (cam != nullptr) {
                mEnumerator->closeCamera(cam);
            }
        }
        mActiveCameras.clear();
    }

  protected:
    void loadCameraList() {
        // SetUp() must run first!
        ASSERT_NE(mEnumerator, nullptr);

        // Get the camera list
        ASSERT_TRUE(mEnumerator->getCameraList(&mCameraInfo).isOk())
                << "Failed to get a list of available cameras";
        LOG(INFO) << "We have " << mCameraInfo.size() << " cameras.";
    }

    void loadUltrasonicsArrayList() {
        // SetUp() must run first!
        ASSERT_NE(mEnumerator, nullptr);

        // Get the ultrasonics array list
        auto result = mEnumerator->getUltrasonicsArrayList(&mUltrasonicsArraysInfo);
        ASSERT_TRUE(result.isOk() ||
                // TODO(b/149874793): Remove below conditions when
                // getUltrasonicsArrayList() is implemented.
                (!result.isOk() && result.getServiceSpecificError() ==
                        static_cast<int32_t>(EvsResult::NOT_IMPLEMENTED)))
                << "Failed to get a list of available ultrasonics arrays";
        LOG(INFO) << "We have " << mCameraInfo.size() << " ultrasonics arrays.";
    }

    bool isLogicalCamera(const camera_metadata_t* metadata) {
        if (metadata == nullptr) {
            // A logical camera device must have a valid camera metadata.
            return false;
        }

        // Looking for LOGICAL_MULTI_CAMERA capability from metadata.
        camera_metadata_ro_entry_t entry;
        int rc = find_camera_metadata_ro_entry(metadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
                                               &entry);
        if (rc != 0) {
            // No capabilities are found.
            return false;
        }

        for (size_t i = 0; i < entry.count; ++i) {
            uint8_t cap = entry.data.u8[i];
            if (cap == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
                return true;
            }
        }

        return false;
    }

    std::unordered_set<std::string> getPhysicalCameraIds(const std::string& id, bool& flag) {
        std::unordered_set<std::string> physicalCameras;
        const auto it = std::find_if(mCameraInfo.begin(), mCameraInfo.end(),
                                     [&id](const CameraDesc& desc) { return id == desc.id; });
        if (it == mCameraInfo.end()) {
            // Unknown camera is requested.  Return an empty list.
            return physicalCameras;
        }

        const camera_metadata_t* metadata = reinterpret_cast<camera_metadata_t*>(&it->metadata[0]);
        flag = isLogicalCamera(metadata);
        if (!flag) {
            // EVS assumes that the device w/o a valid metadata is a physical
            // device.
            LOG(INFO) << id << " is not a logical camera device.";
            physicalCameras.insert(id);
            return physicalCameras;
        }

        // Look for physical camera identifiers
        camera_metadata_ro_entry entry;
        int rc = find_camera_metadata_ro_entry(metadata, ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
                                               &entry);
        if (rc != 0) {
            LOG(ERROR) << "No physical camera ID is found for a logical camera device";
        }

        const uint8_t* ids = entry.data.u8;
        size_t start = 0;
        for (size_t i = 0; i < entry.count; ++i) {
            if (ids[i] == '\0') {
                if (start != i) {
                    std::string id(reinterpret_cast<const char*>(ids + start));
                    physicalCameras.insert(id);
                }
                start = i + 1;
            }
        }

        LOG(INFO) << id << " consists of " << physicalCameras.size() << " physical camera devices";
        return physicalCameras;
    }

    Stream getFirstStreamConfiguration(camera_metadata_t* metadata) {
        Stream targetCfg = {};
        camera_metadata_entry_t streamCfgs;
        if (!find_camera_metadata_entry(metadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                                        &streamCfgs)) {
            // Stream configurations are found in metadata
            RawStreamConfig* ptr = reinterpret_cast<RawStreamConfig*>(streamCfgs.data.i32);
            for (unsigned offset = 0; offset < streamCfgs.count; offset += kStreamCfgSz) {
                if (ptr->direction == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
                    targetCfg.width = ptr->width;
                    targetCfg.height = ptr->height;
                    targetCfg.format = static_cast<PixelFormat>(ptr->format);
                    break;
                }
                ++ptr;
            }
        }

        return targetCfg;
    }

    class DeviceStatusCallback : public BnEvsEnumeratorStatusCallback {
        ndk::ScopedAStatus deviceStatusChanged(const std::vector<DeviceStatus>&) override {
            // This empty implementation returns always ok().
            return ndk::ScopedAStatus::ok();
        }
    };

    // Every test needs access to the service
    std::shared_ptr<IEvsEnumerator> mEnumerator;
    // Empty unless/util loadCameraList() is called
    std::vector<CameraDesc> mCameraInfo;
    // boolean to tell current module under testing is HW module implementation
    // or not
    bool mIsHwModule;
    // A list of active camera handles that are need to be cleaned up
    std::deque<std::shared_ptr<IEvsCamera>> mActiveCameras;
    // Empty unless/util loadUltrasonicsArrayList() is called
    std::vector<UltrasonicsArrayDesc> mUltrasonicsArraysInfo;
    // A list of active ultrasonics array handles that are to be cleaned up
    std::deque<std::weak_ptr<IEvsUltrasonicsArray>> mActiveUltrasonicsArrays;
};

// Test cases, their implementations, and corresponding requirements are
// documented at go/aae-evs-public-api-test.

/*
 * CameraOpenClean:
 * Opens each camera reported by the enumerator and then explicitly closes it via a
 * call to closeCamera.  Then repeats the test to ensure all cameras can be reopened.
 */
TEST_P(EvsAidlTest, CameraOpenClean) {
    LOG(INFO) << "Starting CameraOpenClean test";

    // Get the camera list
    loadCameraList();

    // Open and close each camera twice
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        auto devices = getPhysicalCameraIds(cam.id, isLogicalCam);
        if (mIsHwModule && isLogicalCam) {
            LOG(INFO) << "Skip a logical device, " << cam.id << " for HW target.";
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        for (int pass = 0; pass < 2; pass++) {
            std::shared_ptr<IEvsCamera> pCam;
            ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
            ASSERT_NE(pCam, nullptr);

            CameraDesc cameraInfo;
            for (auto&& devName : devices) {
                ASSERT_TRUE(pCam->getPhysicalCameraInfo(devName, &cameraInfo).isOk());
                EXPECT_EQ(devName, cameraInfo.id);
            }

            // Store a camera handle for a clean-up
            mActiveCameras.push_back(pCam);

            // Verify that this camera self-identifies correctly
            ASSERT_TRUE(pCam->getCameraInfo(&cameraInfo).isOk());
            EXPECT_EQ(cam.id, cameraInfo.id);

            // Verify methods for extended info
            const auto id = 0xFFFFFFFF;  // meaningless id
            std::vector<uint8_t> values;
            auto status = pCam->setExtendedInfo(id, values);
            if (isLogicalCam) {
                EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
                                                      static_cast<int>(EvsResult::NOT_SUPPORTED));
            } else {
                EXPECT_TRUE(status.isOk());
            }

            status = pCam->getExtendedInfo(id, &values);
            if (isLogicalCam) {
                EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
                                                      static_cast<int>(EvsResult::NOT_SUPPORTED));
            } else {
                EXPECT_TRUE(status.isOk());
            }

            // Explicitly close the camera so resources are released right away
            ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
            mActiveCameras.clear();
        }
    }
}

/*
 * CameraOpenAggressive:
 * Opens each camera reported by the enumerator twice in a row without an intervening closeCamera
 * call.  This ensures that the intended "aggressive open" behavior works.  This is necessary for
 * the system to be tolerant of shutdown/restart race conditions.
 */
TEST_P(EvsAidlTest, CameraOpenAggressive) {
    LOG(INFO) << "Starting CameraOpenAggressive test";

    // Get the camera list
    loadCameraList();

    // Open and close each camera twice
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (mIsHwModule && isLogicalCam) {
            LOG(INFO) << "Skip a logical device, " << cam.id << " for HW target.";
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        mActiveCameras.clear();
        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam);

        // Verify that this camera self-identifies correctly
        CameraDesc cameraInfo;
        ASSERT_TRUE(pCam->getCameraInfo(&cameraInfo).isOk());
        EXPECT_EQ(cam.id, cameraInfo.id);

        std::shared_ptr<IEvsCamera> pCam2;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam2).isOk());
        EXPECT_NE(pCam2, nullptr);
        EXPECT_NE(pCam, pCam2);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam2);

        auto status = pCam->setMaxFramesInFlight(2);
        if (mIsHwModule) {
            // Verify that the old camera rejects calls via HW module.
            EXPECT_TRUE(!status.isOk() && status.getServiceSpecificError() ==
                                                  static_cast<int>(EvsResult::OWNERSHIP_LOST));
        } else {
            // default implementation supports multiple clients.
            EXPECT_TRUE(status.isOk());
        }

        // Close the superseded camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.pop_front();

        // Verify that the second camera instance self-identifies correctly
        ASSERT_TRUE(pCam2->getCameraInfo(&cameraInfo).isOk());
        EXPECT_EQ(cam.id, cameraInfo.id);

        // Close the second camera instance
        ASSERT_TRUE(mEnumerator->closeCamera(pCam2).isOk());
        mActiveCameras.pop_front();
    }

    // Sleep here to ensure the destructor cleanup has time to run so we don't break follow on tests
    sleep(1);  // I hate that this is an arbitrary time to wait.  :(  b/36122635
}

/*
 * CameraStreamPerformance:
 * Measure and qualify the stream start up time and streaming frame rate of each reported camera
 */
TEST_P(EvsAidlTest, CameraStreamPerformance) {
    LOG(INFO) << "Starting CameraStreamPerformance test";

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        auto devices = getPhysicalCameraIds(cam.id, isLogicalCam);
        if (mIsHwModule && isLogicalCam) {
            LOG(INFO) << "Skip a logical device " << cam.id;
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam);

        // Set up a frame receiver object which will fire up its own thread
        std::shared_ptr<FrameHandler> frameHandler = ndk::SharedRefBase::make<FrameHandler>(
                pCam, cam, nullptr, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler, nullptr);

        // Start the camera's video stream
        nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
        ASSERT_TRUE(frameHandler->startStream());

        // Ensure the first frame arrived within the expected time
        frameHandler->waitForFrameCount(1);
        nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC);
        nsecs_t timeToFirstFrame = systemTime(SYSTEM_TIME_MONOTONIC) - start;

        // Extra delays are expected when we attempt to start a video stream on
        // the logical camera device.  The amount of delay is expected the
        // number of physical camera devices multiplied by
        // kMaxStreamStartMilliseconds at most.
        EXPECT_LE(nanoseconds_to_milliseconds(timeToFirstFrame),
                  kMaxStreamStartMilliseconds * devices.size());
        printf("%s: Measured time to first frame %0.2f ms\n", cam.id.data(),
               timeToFirstFrame * kNanoToMilliseconds);
        LOG(INFO) << cam.id << ": Measured time to first frame " << std::scientific
                  << timeToFirstFrame * kNanoToMilliseconds << " ms.";

        // Check aspect ratio
        unsigned width = 0, height = 0;
        frameHandler->getFrameDimension(&width, &height);
        EXPECT_GE(width, height);

        // Wait a bit, then ensure we get at least the required minimum number of frames
        sleep(5);
        nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);

        // Even when the camera pointer goes out of scope, the FrameHandler object will
        // keep the stream alive unless we tell it to shutdown.
        // Also note that the FrameHandle and the Camera have a mutual circular reference, so
        // we have to break that cycle in order for either of them to get cleaned up.
        frameHandler->shutdown();

        unsigned framesReceived = 0;
        frameHandler->getFramesCounters(&framesReceived, nullptr);
        framesReceived = framesReceived - 1;  // Back out the first frame we already waited for
        nsecs_t runTime = end - firstFrame;
        float framesPerSecond = framesReceived / (runTime * kNanoToSeconds);
        printf("Measured camera rate %3.2f fps\n", framesPerSecond);
        LOG(INFO) << "Measured camera rate " << std::scientific << framesPerSecond << " fps.";
        EXPECT_GE(framesPerSecond, kMinimumFramesPerSecond);

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.clear();
    }
}

/*
 * CameraStreamBuffering:
 * Ensure the camera implementation behaves properly when the client holds onto buffers for more
 * than one frame time.  The camera must cleanly skip frames until the client is ready again.
 */
TEST_P(EvsAidlTest, CameraStreamBuffering) {
    LOG(INFO) << "Starting CameraStreamBuffering test";

    // Arbitrary constant (should be > 1 and not too big)
    static const unsigned int kBuffersToHold = 6;

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (mIsHwModule && isLogicalCam) {
            LOG(INFO) << "Skip a logical device " << cam.id << " for HW target.";
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam);

        // Ask for a very large number of buffers in flight to ensure it errors correctly
        auto badResult = pCam->setMaxFramesInFlight(std::numeric_limits<int32_t>::max());
        EXPECT_TRUE(!badResult.isOk() && badResult.getServiceSpecificError() ==
                                                 static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));

        // Now ask for exactly two buffers in flight as we'll test behavior in that case
        ASSERT_TRUE(pCam->setMaxFramesInFlight(kBuffersToHold).isOk());

        // Set up a frame receiver object which will fire up its own thread.
        std::shared_ptr<FrameHandler> frameHandler = ndk::SharedRefBase::make<FrameHandler>(
                pCam, cam, nullptr, FrameHandler::eNoAutoReturn);
        EXPECT_NE(frameHandler, nullptr);

        // Start the camera's video stream
        ASSERT_TRUE(frameHandler->startStream());

        // Check that the video stream stalls once we've gotten exactly the number of buffers
        // we requested since we told the frameHandler not to return them.
        sleep(1);  // 1 second should be enough for at least 5 frames to be delivered worst case
        unsigned framesReceived = 0;
        frameHandler->getFramesCounters(&framesReceived, nullptr);
        ASSERT_EQ(kBuffersToHold, framesReceived) << "Stream didn't stall at expected buffer limit";

        // Give back one buffer
        ASSERT_TRUE(frameHandler->returnHeldBuffer());

        // Once we return a buffer, it shouldn't take more than 1/10 second to get a new one
        // filled since we require 10fps minimum -- but give a 10% allowance just in case.
        usleep(110 * kMillisecondsToMicroseconds);
        frameHandler->getFramesCounters(&framesReceived, nullptr);
        EXPECT_EQ(kBuffersToHold + 1, framesReceived) << "Stream should've resumed";

        // Even when the camera pointer goes out of scope, the FrameHandler object will
        // keep the stream alive unless we tell it to shutdown.
        // Also note that the FrameHandle and the Camera have a mutual circular reference, so
        // we have to break that cycle in order for either of them to get cleaned up.
        frameHandler->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.clear();
    }
}

/*
 * CameraToDisplayRoundTrip:
 * End to end test of data flowing from the camera to the display.  Each delivered frame of camera
 * imagery is simply copied to the display buffer and presented on screen.  This is the one test
 * which a human could observe to see the operation of the system on the physical display.
 */
TEST_P(EvsAidlTest, CameraToDisplayRoundTrip) {
    LOG(INFO) << "Starting CameraToDisplayRoundTrip test";

    // Get the camera list
    loadCameraList();

    // Request available display IDs
    uint8_t targetDisplayId = 0;
    std::vector<uint8_t> displayIds;
    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
    EXPECT_GT(displayIds.size(), 0);
    targetDisplayId = displayIds[0];

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        // Request exclusive access to the first EVS display
        std::shared_ptr<IEvsDisplay> pDisplay;
        ASSERT_TRUE(mEnumerator->openDisplay(targetDisplayId, &pDisplay).isOk());
        EXPECT_NE(pDisplay, nullptr);
        LOG(INFO) << "Display " << static_cast<int>(targetDisplayId) << " is in use.";

        // Get the display descriptor
        DisplayDesc displayDesc;
        ASSERT_TRUE(pDisplay->getDisplayInfo(&displayDesc).isOk());
        LOG(INFO) << "    Resolution: " << displayDesc.width << "x" << displayDesc.height;
        ASSERT_GT(displayDesc.width, 0);
        ASSERT_GT(displayDesc.height, 0);

        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (mIsHwModule && isLogicalCam) {
            LOG(INFO) << "Skip a logical device " << cam.id << " for HW target.";
            ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam);

        // Set up a frame receiver object which will fire up its own thread.
        std::shared_ptr<FrameHandler> frameHandler = ndk::SharedRefBase::make<FrameHandler>(
                pCam, cam, pDisplay, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler, nullptr);

        // Activate the display
        ASSERT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());

        // Start the camera's video stream
        ASSERT_TRUE(frameHandler->startStream());

        // Wait a while to let the data flow
        static const int kSecondsToWait = 5;
        const int streamTimeMs =
                kSecondsToWait * kSecondsToMilliseconds - kMaxStreamStartMilliseconds;
        const unsigned minimumFramesExpected =
                streamTimeMs * kMinimumFramesPerSecond / kSecondsToMilliseconds;
        sleep(kSecondsToWait);
        unsigned framesReceived = 0;
        unsigned framesDisplayed = 0;
        frameHandler->getFramesCounters(&framesReceived, &framesDisplayed);
        EXPECT_EQ(framesReceived, framesDisplayed);
        EXPECT_GE(framesDisplayed, minimumFramesExpected);

        // Turn off the display (yes, before the stream stops -- it should be handled)
        ASSERT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());

        // Shut down the streamer
        frameHandler->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.clear();

        // Explicitly release the display
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
    }
}

/*
 * MultiCameraStream:
 * Verify that each client can start and stop video streams on the same
 * underlying camera.
 */
TEST_P(EvsAidlTest, MultiCameraStream) {
    LOG(INFO) << "Starting MultiCameraStream test";

    if (mIsHwModule) {
        // This test is not for HW module implementation.
        return;
    }

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        // Create two camera clients.
        std::shared_ptr<IEvsCamera> pCam0;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam0).isOk());
        EXPECT_NE(pCam0, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam0);

        std::shared_ptr<IEvsCamera> pCam1;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam1).isOk());
        EXPECT_NE(pCam1, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam1);

        // Set up per-client frame receiver objects which will fire up its own thread
        std::shared_ptr<FrameHandler> frameHandler0 = ndk::SharedRefBase::make<FrameHandler>(
                pCam0, cam, nullptr, FrameHandler::eAutoReturn);
        std::shared_ptr<FrameHandler> frameHandler1 = ndk::SharedRefBase::make<FrameHandler>(
                pCam1, cam, nullptr, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler0, nullptr);
        EXPECT_NE(frameHandler1, nullptr);

        // Start the camera's video stream via client 0
        ASSERT_TRUE(frameHandler0->startStream());
        ASSERT_TRUE(frameHandler1->startStream());

        // Ensure the stream starts
        frameHandler0->waitForFrameCount(1);
        frameHandler1->waitForFrameCount(1);

        nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC);

        // Wait a bit, then ensure both clients get at least the required minimum number of frames
        sleep(5);
        nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
        unsigned framesReceived0 = 0, framesReceived1 = 0;
        frameHandler0->getFramesCounters(&framesReceived0, nullptr);
        frameHandler1->getFramesCounters(&framesReceived1, nullptr);
        framesReceived0 = framesReceived0 - 1;  // Back out the first frame we already waited for
        framesReceived1 = framesReceived1 - 1;  // Back out the first frame we already waited for
        nsecs_t runTime = end - firstFrame;
        float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
        float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
        LOG(INFO) << "Measured camera rate " << std::scientific << framesPerSecond0 << " fps and "
                  << framesPerSecond1 << " fps";
        EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
        EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);

        // Shutdown one client
        frameHandler0->shutdown();

        // Read frame counters again
        frameHandler0->getFramesCounters(&framesReceived0, nullptr);
        frameHandler1->getFramesCounters(&framesReceived1, nullptr);

        // Wait a bit again
        sleep(5);
        unsigned framesReceivedAfterStop0 = 0, framesReceivedAfterStop1 = 0;
        frameHandler0->getFramesCounters(&framesReceivedAfterStop0, nullptr);
        frameHandler1->getFramesCounters(&framesReceivedAfterStop1, nullptr);
        EXPECT_EQ(framesReceived0, framesReceivedAfterStop0);
        EXPECT_LT(framesReceived1, framesReceivedAfterStop1);

        // Shutdown another
        frameHandler1->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam0).isOk());
        ASSERT_TRUE(mEnumerator->closeCamera(pCam1).isOk());
        mActiveCameras.clear();

        // TODO(b/145459970, b/145457727): below sleep() is added to ensure the
        // destruction of active camera objects; this may be related with two
        // issues.
        sleep(1);
    }
}

/*
 * CameraParameter:
 * Verify that a client can adjust a camera parameter.
 */
TEST_P(EvsAidlTest, CameraParameter) {
    LOG(INFO) << "Starting CameraParameter test";

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (isLogicalCam) {
            // TODO(b/145465724): Support camera parameter programming on
            // logical devices.
            LOG(INFO) << "Skip a logical device " << cam.id;
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        // Create a camera client
        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera
        mActiveCameras.push_back(pCam);

        // Get the parameter list
        std::vector<CameraParam> cmds;
        ASSERT_TRUE(pCam->getParameterList(&cmds).isOk());
        if (cmds.size() < 1) {
            continue;
        }

        // Set up per-client frame receiver objects which will fire up its own thread
        std::shared_ptr<FrameHandler> frameHandler = ndk::SharedRefBase::make<FrameHandler>(
                pCam, cam, nullptr, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler, nullptr);

        // Start the camera's video stream
        ASSERT_TRUE(frameHandler->startStream());

        // Ensure the stream starts
        frameHandler->waitForFrameCount(1);

        // Set current client is the primary client
        ASSERT_TRUE(pCam->setPrimaryClient().isOk());
        for (auto& cmd : cmds) {
            // Get a valid parameter value range
            ParameterRange range;
            ASSERT_TRUE(pCam->getIntParameterRange(cmd, &range).isOk());

            std::vector<int32_t> values;
            if (cmd == CameraParam::ABSOLUTE_FOCUS) {
                // Try to turn off auto-focus
                ASSERT_TRUE(pCam->setIntParameter(CameraParam::AUTO_FOCUS, 0, &values).isOk());
                for (auto&& v : values) {
                    EXPECT_EQ(v, 0);
                }
            }

            // Try to program a parameter with a random value [minVal, maxVal]
            int32_t val0 = range.min + (std::rand() % (range.max - range.min));

            // Rounding down
            val0 = val0 - (val0 % range.step);
            values.clear();
            ASSERT_TRUE(pCam->setIntParameter(cmd, val0, &values).isOk());

            values.clear();
            ASSERT_TRUE(pCam->getIntParameter(cmd, &values).isOk());
            for (auto&& v : values) {
                EXPECT_EQ(val0, v) << "Values are not matched.";
            }
        }
        ASSERT_TRUE(pCam->unsetPrimaryClient().isOk());

        // Shutdown
        frameHandler->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.clear();
    }
}

/*
 * CameraPrimaryClientRelease
 * Verify that non-primary client gets notified when the primary client either
 * terminates or releases a role.
 */
TEST_P(EvsAidlTest, CameraPrimaryClientRelease) {
    LOG(INFO) << "Starting CameraPrimaryClientRelease test";

    if (mIsHwModule) {
        // This test is not for HW module implementation.
        return;
    }

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (isLogicalCam) {
            // TODO(b/145465724): Support camera parameter programming on
            // logical devices.
            LOG(INFO) << "Skip a logical device " << cam.id;
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        // Create two camera clients.
        std::shared_ptr<IEvsCamera> pPrimaryCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pPrimaryCam).isOk());
        EXPECT_NE(pPrimaryCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pPrimaryCam);

        std::shared_ptr<IEvsCamera> pSecondaryCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pSecondaryCam).isOk());
        EXPECT_NE(pSecondaryCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pSecondaryCam);

        // Set up per-client frame receiver objects which will fire up its own thread
        std::shared_ptr<FrameHandler> frameHandlerPrimary = ndk::SharedRefBase::make<FrameHandler>(
                pPrimaryCam, cam, nullptr, FrameHandler::eAutoReturn);
        std::shared_ptr<FrameHandler> frameHandlerSecondary =
                ndk::SharedRefBase::make<FrameHandler>(pSecondaryCam, cam, nullptr,
                                                       FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandlerPrimary, nullptr);
        EXPECT_NE(frameHandlerSecondary, nullptr);

        // Set one client as the primary client
        ASSERT_TRUE(pPrimaryCam->setPrimaryClient().isOk());

        // Try to set another client as the primary client.
        ASSERT_FALSE(pSecondaryCam->setPrimaryClient().isOk());

        // Start the camera's video stream via a primary client client.
        ASSERT_TRUE(frameHandlerPrimary->startStream());

        // Ensure the stream starts
        frameHandlerPrimary->waitForFrameCount(1);

        // Start the camera's video stream via another client
        ASSERT_TRUE(frameHandlerSecondary->startStream());

        // Ensure the stream starts
        frameHandlerSecondary->waitForFrameCount(1);

        // Non-primary client expects to receive a primary client role relesed
        // notification.
        EvsEventDesc aTargetEvent = {};
        EvsEventDesc aNotification = {};

        bool listening = false;
        std::mutex eventLock;
        std::condition_variable eventCond;
        std::thread listener =
                std::thread([&aNotification, &frameHandlerSecondary, &listening, &eventCond]() {
                    // Notify that a listening thread is running.
                    listening = true;
                    eventCond.notify_all();

                    EvsEventDesc aTargetEvent;
                    aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
                    if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification, true)) {
                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                    }
                });

        // Wait until a listening thread starts.
        std::unique_lock<std::mutex> lock(eventLock);
        auto timer = std::chrono::system_clock::now();
        while (!listening) {
            timer += 1s;
            eventCond.wait_until(lock, timer);
        }
        lock.unlock();

        // Release a primary client role.
        ASSERT_TRUE(pPrimaryCam->unsetPrimaryClient().isOk());

        // Join a listening thread.
        if (listener.joinable()) {
            listener.join();
        }

        // Verify change notifications.
        ASSERT_EQ(EvsEventType::MASTER_RELEASED, static_cast<EvsEventType>(aNotification.aType));

        // Non-primary becomes a primary client.
        ASSERT_TRUE(pSecondaryCam->setPrimaryClient().isOk());

        // Previous primary client fails to become a primary client.
        ASSERT_FALSE(pPrimaryCam->setPrimaryClient().isOk());

        listening = false;
        listener = std::thread([&aNotification, &frameHandlerPrimary, &listening, &eventCond]() {
            // Notify that a listening thread is running.
            listening = true;
            eventCond.notify_all();

            EvsEventDesc aTargetEvent;
            aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
            if (!frameHandlerPrimary->waitForEvent(aTargetEvent, aNotification, true)) {
                LOG(WARNING) << "A timer is expired before a target event is fired.";
            }
        });

        // Wait until a listening thread starts.
        timer = std::chrono::system_clock::now();
        lock.lock();
        while (!listening) {
            eventCond.wait_until(lock, timer + 1s);
        }
        lock.unlock();

        // Closing current primary client.
        frameHandlerSecondary->shutdown();

        // Join a listening thread.
        if (listener.joinable()) {
            listener.join();
        }

        // Verify change notifications.
        ASSERT_EQ(EvsEventType::MASTER_RELEASED, static_cast<EvsEventType>(aNotification.aType));

        // Closing streams.
        frameHandlerPrimary->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pPrimaryCam).isOk());
        ASSERT_TRUE(mEnumerator->closeCamera(pSecondaryCam).isOk());
        mActiveCameras.clear();
    }
}

/*
 * MultiCameraParameter:
 * Verify that primary and non-primary clients behave as expected when they try to adjust
 * camera parameters.
 */
TEST_P(EvsAidlTest, MultiCameraParameter) {
    LOG(INFO) << "Starting MultiCameraParameter test";

    if (mIsHwModule) {
        // This test is not for HW module implementation.
        return;
    }

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (isLogicalCam) {
            // TODO(b/145465724): Support camera parameter programming on
            // logical devices.
            LOG(INFO) << "Skip a logical device " << cam.id;
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        // Create two camera clients.
        std::shared_ptr<IEvsCamera> pPrimaryCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pPrimaryCam).isOk());
        EXPECT_NE(pPrimaryCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pPrimaryCam);

        std::shared_ptr<IEvsCamera> pSecondaryCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pSecondaryCam).isOk());
        EXPECT_NE(pSecondaryCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pSecondaryCam);

        // Get the parameter list
        std::vector<CameraParam> camPrimaryCmds, camSecondaryCmds;
        ASSERT_TRUE(pPrimaryCam->getParameterList(&camPrimaryCmds).isOk());
        ASSERT_TRUE(pSecondaryCam->getParameterList(&camSecondaryCmds).isOk());
        if (camPrimaryCmds.size() < 1 || camSecondaryCmds.size() < 1) {
            // Skip a camera device if it does not support any parameter.
            continue;
        }

        // Set up per-client frame receiver objects which will fire up its own thread
        std::shared_ptr<FrameHandler> frameHandlerPrimary = ndk::SharedRefBase::make<FrameHandler>(
                pPrimaryCam, cam, nullptr, FrameHandler::eAutoReturn);
        std::shared_ptr<FrameHandler> frameHandlerSecondary =
                ndk::SharedRefBase::make<FrameHandler>(pSecondaryCam, cam, nullptr,
                                                       FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandlerPrimary, nullptr);
        EXPECT_NE(frameHandlerSecondary, nullptr);

        // Set one client as the primary client.
        ASSERT_TRUE(pPrimaryCam->setPrimaryClient().isOk());

        // Try to set another client as the primary client.
        ASSERT_FALSE(pSecondaryCam->setPrimaryClient().isOk());

        // Start the camera's video stream via a primary client client.
        ASSERT_TRUE(frameHandlerPrimary->startStream());

        // Ensure the stream starts
        frameHandlerPrimary->waitForFrameCount(1);

        // Start the camera's video stream via another client
        ASSERT_TRUE(frameHandlerSecondary->startStream());

        // Ensure the stream starts
        frameHandlerSecondary->waitForFrameCount(1);

        int32_t val0 = 0;
        std::vector<int32_t> values;
        EvsEventDesc aNotification0 = {};
        EvsEventDesc aNotification1 = {};
        for (auto& cmd : camPrimaryCmds) {
            // Get a valid parameter value range
            ParameterRange range;
            ASSERT_TRUE(pPrimaryCam->getIntParameterRange(cmd, &range).isOk());
            if (cmd == CameraParam::ABSOLUTE_FOCUS) {
                // Try to turn off auto-focus
                values.clear();
                ASSERT_TRUE(
                        pPrimaryCam->setIntParameter(CameraParam::AUTO_FOCUS, 0, &values).isOk());
                for (auto&& v : values) {
                    EXPECT_EQ(v, 0);
                }
            }

            // Calculate a parameter value to program.
            val0 = range.min + (std::rand() % (range.max - range.min));
            val0 = val0 - (val0 % range.step);

            // Prepare and start event listeners.
            bool listening0 = false;
            bool listening1 = false;
            std::condition_variable eventCond;
            std::thread listener0 = std::thread([cmd, val0, &aNotification0, &frameHandlerPrimary,
                                                 &listening0, &listening1, &eventCond]() {
                listening0 = true;
                if (listening1) {
                    eventCond.notify_all();
                }

                EvsEventDesc aTargetEvent;
                aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                aTargetEvent.payload.push_back(static_cast<int32_t>(cmd));
                aTargetEvent.payload.push_back(val0);
                if (!frameHandlerPrimary->waitForEvent(aTargetEvent, aNotification0)) {
                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                }
            });
            std::thread listener1 = std::thread([cmd, val0, &aNotification1, &frameHandlerSecondary,
                                                 &listening0, &listening1, &eventCond]() {
                listening1 = true;
                if (listening0) {
                    eventCond.notify_all();
                }

                EvsEventDesc aTargetEvent;
                aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                aTargetEvent.payload.push_back(static_cast<int32_t>(cmd));
                aTargetEvent.payload.push_back(val0);
                if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification1)) {
                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                }
            });

            // Wait until a listening thread starts.
            std::mutex eventLock;
            std::unique_lock<std::mutex> lock(eventLock);
            auto timer = std::chrono::system_clock::now();
            while (!listening0 || !listening1) {
                eventCond.wait_until(lock, timer + 1s);
            }
            lock.unlock();

            // Try to program a parameter
            values.clear();
            ASSERT_TRUE(pPrimaryCam->setIntParameter(cmd, val0, &values).isOk());
            for (auto&& v : values) {
                EXPECT_EQ(val0, v) << "Values are not matched.";
            }

            // Join a listening thread.
            if (listener0.joinable()) {
                listener0.join();
            }
            if (listener1.joinable()) {
                listener1.join();
            }

            // Verify a change notification
            ASSERT_EQ(EvsEventType::PARAMETER_CHANGED,
                      static_cast<EvsEventType>(aNotification0.aType));
            ASSERT_EQ(EvsEventType::PARAMETER_CHANGED,
                      static_cast<EvsEventType>(aNotification1.aType));
            ASSERT_GE(aNotification0.payload.size(), 2);
            ASSERT_GE(aNotification1.payload.size(), 2);
            ASSERT_EQ(cmd, static_cast<CameraParam>(aNotification0.payload[0]));
            ASSERT_EQ(cmd, static_cast<CameraParam>(aNotification1.payload[0]));
            for (auto&& v : values) {
                ASSERT_EQ(v, aNotification0.payload[1]);
                ASSERT_EQ(v, aNotification1.payload[1]);
            }

            // Clients expects to receive a parameter change notification
            // whenever a primary client client adjusts it.
            values.clear();
            ASSERT_TRUE(pPrimaryCam->getIntParameter(cmd, &values).isOk());
            for (auto&& v : values) {
                EXPECT_EQ(val0, v) << "Values are not matched.";
            }
        }

        // Try to adjust a parameter via non-primary client
        values.clear();
        ASSERT_FALSE(pSecondaryCam->setIntParameter(camSecondaryCmds[0], val0, &values).isOk());

        // Non-primary client attempts to be a primary client
        ASSERT_FALSE(pSecondaryCam->setPrimaryClient().isOk());

        // Primary client retires from a primary client role
        bool listening = false;
        std::condition_variable eventCond;
        std::thread listener =
                std::thread([&aNotification0, &frameHandlerSecondary, &listening, &eventCond]() {
                    listening = true;
                    eventCond.notify_all();

                    EvsEventDesc aTargetEvent;
                    aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
                    if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification0, true)) {
                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                    }
                });

        std::mutex eventLock;
        auto timer = std::chrono::system_clock::now();
        std::unique_lock<std::mutex> lock(eventLock);
        while (!listening) {
            eventCond.wait_until(lock, timer + 1s);
        }
        lock.unlock();

        ASSERT_TRUE(pPrimaryCam->unsetPrimaryClient().isOk());

        if (listener.joinable()) {
            listener.join();
        }
        ASSERT_EQ(EvsEventType::MASTER_RELEASED, static_cast<EvsEventType>(aNotification0.aType));

        // Try to adjust a parameter after being retired
        values.clear();
        ASSERT_FALSE(pPrimaryCam->setIntParameter(camPrimaryCmds[0], val0, &values).isOk());

        // Non-primary client becomes a primary client
        ASSERT_TRUE(pSecondaryCam->setPrimaryClient().isOk());

        // Try to adjust a parameter via new primary client
        for (auto& cmd : camSecondaryCmds) {
            // Get a valid parameter value range
            ParameterRange range;
            ASSERT_TRUE(pSecondaryCam->getIntParameterRange(cmd, &range).isOk());

            values.clear();
            if (cmd == CameraParam::ABSOLUTE_FOCUS) {
                // Try to turn off auto-focus
                values.clear();
                ASSERT_TRUE(
                        pSecondaryCam->setIntParameter(CameraParam::AUTO_FOCUS, 0, &values).isOk());
                for (auto&& v : values) {
                    EXPECT_EQ(v, 0);
                }
            }

            // Calculate a parameter value to program.  This is being rounding down.
            val0 = range.min + (std::rand() % (range.max - range.min));
            val0 = val0 - (val0 % range.step);

            // Prepare and start event listeners.
            bool listening0 = false;
            bool listening1 = false;
            std::condition_variable eventCond;
            std::thread listener0 = std::thread([&]() {
                listening0 = true;
                if (listening1) {
                    eventCond.notify_all();
                }

                EvsEventDesc aTargetEvent;
                aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                aTargetEvent.payload.push_back(static_cast<int32_t>(cmd));
                aTargetEvent.payload.push_back(val0);
                if (!frameHandlerPrimary->waitForEvent(aTargetEvent, aNotification0)) {
                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                }
            });
            std::thread listener1 = std::thread([&]() {
                listening1 = true;
                if (listening0) {
                    eventCond.notify_all();
                }

                EvsEventDesc aTargetEvent;
                aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                aTargetEvent.payload.push_back(static_cast<int32_t>(cmd));
                aTargetEvent.payload.push_back(val0);
                if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification1)) {
                    LOG(WARNING) << "A timer is expired before a target event is fired.";
                }
            });

            // Wait until a listening thread starts.
            std::mutex eventLock;
            std::unique_lock<std::mutex> lock(eventLock);
            auto timer = std::chrono::system_clock::now();
            while (!listening0 || !listening1) {
                eventCond.wait_until(lock, timer + 1s);
            }
            lock.unlock();

            // Try to program a parameter
            values.clear();
            ASSERT_TRUE(pSecondaryCam->setIntParameter(cmd, val0, &values).isOk());

            // Clients expects to receive a parameter change notification
            // whenever a primary client client adjusts it.
            values.clear();
            ASSERT_TRUE(pSecondaryCam->getIntParameter(cmd, &values).isOk());
            for (auto&& v : values) {
                EXPECT_EQ(val0, v) << "Values are not matched.";
            }

            // Join a listening thread.
            if (listener0.joinable()) {
                listener0.join();
            }
            if (listener1.joinable()) {
                listener1.join();
            }

            // Verify a change notification
            ASSERT_EQ(EvsEventType::PARAMETER_CHANGED,
                      static_cast<EvsEventType>(aNotification0.aType));
            ASSERT_EQ(EvsEventType::PARAMETER_CHANGED,
                      static_cast<EvsEventType>(aNotification1.aType));
            ASSERT_GE(aNotification0.payload.size(), 2);
            ASSERT_GE(aNotification1.payload.size(), 2);
            ASSERT_EQ(cmd, static_cast<CameraParam>(aNotification0.payload[0]));
            ASSERT_EQ(cmd, static_cast<CameraParam>(aNotification1.payload[0]));
            for (auto&& v : values) {
                ASSERT_EQ(v, aNotification0.payload[1]);
                ASSERT_EQ(v, aNotification1.payload[1]);
            }
        }

        // New primary client retires from the role
        ASSERT_TRUE(pSecondaryCam->unsetPrimaryClient().isOk());

        // Shutdown
        frameHandlerPrimary->shutdown();
        frameHandlerSecondary->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pPrimaryCam).isOk());
        ASSERT_TRUE(mEnumerator->closeCamera(pSecondaryCam).isOk());
        mActiveCameras.clear();
    }
}

/*
 * HighPriorityCameraClient:
 * EVS client, which owns the display, is priortized and therefore can take over
 * a primary client role from other EVS clients without the display.
 */
TEST_P(EvsAidlTest, HighPriorityCameraClient) {
    LOG(INFO) << "Starting HighPriorityCameraClient test";

    if (mIsHwModule) {
        // This test is not for HW module implementation.
        return;
    }

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        if (getPhysicalCameraIds(cam.id, isLogicalCam); isLogicalCam) {
            LOG(INFO) << "Skip a logical device, " << cam.id;
            continue;
        }

        // Request available display IDs
        uint8_t targetDisplayId = 0;
        std::vector<uint8_t> displayIds;
        ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
        EXPECT_GT(displayIds.size(), 0);
        targetDisplayId = displayIds[0];

        // Request exclusive access to the EVS display
        std::shared_ptr<IEvsDisplay> pDisplay;
        ASSERT_TRUE(mEnumerator->openDisplay(targetDisplayId, &pDisplay).isOk());
        EXPECT_NE(pDisplay, nullptr);

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        // Create two clients
        std::shared_ptr<IEvsCamera> pCam0;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam0).isOk());
        EXPECT_NE(pCam0, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam0);

        std::shared_ptr<IEvsCamera> pCam1;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam1).isOk());
        EXPECT_NE(pCam1, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam1);

        // Get the parameter list; this test will use the first command in both
        // lists.
        std::vector<CameraParam> cam0Cmds, cam1Cmds;
        ASSERT_TRUE(pCam0->getParameterList(&cam0Cmds).isOk());
        ASSERT_TRUE(pCam1->getParameterList(&cam1Cmds).isOk());
        if (cam0Cmds.size() < 1 || cam1Cmds.size() < 1) {
            // Cannot execute this test.
            ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
            continue;
        }

        // Set up a frame receiver object which will fire up its own thread.
        std::shared_ptr<FrameHandler> frameHandler0 = ndk::SharedRefBase::make<FrameHandler>(
                pCam0, cam, nullptr, FrameHandler::eAutoReturn);
        std::shared_ptr<FrameHandler> frameHandler1 = ndk::SharedRefBase::make<FrameHandler>(
                pCam1, cam, nullptr, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler0, nullptr);
        EXPECT_NE(frameHandler1, nullptr);

        // Activate the display
        ASSERT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());

        // Start the camera's video stream
        ASSERT_TRUE(frameHandler0->startStream());
        ASSERT_TRUE(frameHandler1->startStream());

        // Ensure the stream starts
        frameHandler0->waitForFrameCount(1);
        frameHandler1->waitForFrameCount(1);

        // Client 1 becomes a primary client and programs a parameter.

        // Get a valid parameter value range
        ParameterRange range;
        ASSERT_TRUE(pCam1->getIntParameterRange(cam1Cmds[0], &range).isOk());

        // Client1 becomes a primary client
        ASSERT_TRUE(pCam1->setPrimaryClient().isOk());

        std::vector<int32_t> values;
        EvsEventDesc aTargetEvent = {};
        EvsEventDesc aNotification = {};
        bool listening = false;
        std::mutex eventLock;
        std::condition_variable eventCond;
        if (cam1Cmds[0] == CameraParam::ABSOLUTE_FOCUS) {
            std::thread listener =
                    std::thread([&frameHandler0, &aNotification, &listening, &eventCond] {
                        listening = true;
                        eventCond.notify_all();

                        EvsEventDesc aTargetEvent;
                        aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                        aTargetEvent.payload.push_back(
                                static_cast<int32_t>(CameraParam::AUTO_FOCUS));
                        aTargetEvent.payload.push_back(0);
                        if (!frameHandler0->waitForEvent(aTargetEvent, aNotification)) {
                            LOG(WARNING) << "A timer is expired before a target event is fired.";
                        }
                    });

            // Wait until a lister starts.
            std::unique_lock<std::mutex> lock(eventLock);
            auto timer = std::chrono::system_clock::now();
            while (!listening) {
                eventCond.wait_until(lock, timer + 1s);
            }
            lock.unlock();

            // Try to turn off auto-focus
            ASSERT_TRUE(pCam1->setIntParameter(CameraParam::AUTO_FOCUS, 0, &values).isOk());
            for (auto&& v : values) {
                EXPECT_EQ(v, 0);
            }

            // Join a listener
            if (listener.joinable()) {
                listener.join();
            }

            // Make sure AUTO_FOCUS is off.
            ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType),
                      EvsEventType::PARAMETER_CHANGED);
        }

        // Try to program a parameter with a random value [minVal, maxVal] after
        // rounding it down.
        int32_t val0 = range.min + (std::rand() % (range.max - range.min));
        val0 = val0 - (val0 % range.step);

        std::thread listener = std::thread(
                [&frameHandler1, &aNotification, &listening, &eventCond, &cam1Cmds, val0] {
                    listening = true;
                    eventCond.notify_all();

                    EvsEventDesc aTargetEvent;
                    aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                    aTargetEvent.payload.push_back(static_cast<int32_t>(cam1Cmds[0]));
                    aTargetEvent.payload.push_back(val0);
                    if (!frameHandler1->waitForEvent(aTargetEvent, aNotification)) {
                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                    }
                });

        // Wait until a lister starts.
        listening = false;
        std::unique_lock<std::mutex> lock(eventLock);
        auto timer = std::chrono::system_clock::now();
        while (!listening) {
            eventCond.wait_until(lock, timer + 1s);
        }
        lock.unlock();

        values.clear();
        ASSERT_TRUE(pCam1->setIntParameter(cam1Cmds[0], val0, &values).isOk());
        for (auto&& v : values) {
            EXPECT_EQ(val0, v);
        }

        // Join a listener
        if (listener.joinable()) {
            listener.join();
        }

        // Verify a change notification
        ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType), EvsEventType::PARAMETER_CHANGED);
        ASSERT_GE(aNotification.payload.size(), 2);
        ASSERT_EQ(static_cast<CameraParam>(aNotification.payload[0]), cam1Cmds[0]);
        for (auto&& v : values) {
            ASSERT_EQ(v, aNotification.payload[1]);
        }

        listener = std::thread([&frameHandler1, &aNotification, &listening, &eventCond] {
            listening = true;
            eventCond.notify_all();

            EvsEventDesc aTargetEvent;
            aTargetEvent.aType = EvsEventType::MASTER_RELEASED;
            if (!frameHandler1->waitForEvent(aTargetEvent, aNotification, true)) {
                LOG(WARNING) << "A timer is expired before a target event is fired.";
            }
        });

        // Wait until a lister starts.
        listening = false;
        lock.lock();
        timer = std::chrono::system_clock::now();
        while (!listening) {
            eventCond.wait_until(lock, timer + 1s);
        }
        lock.unlock();

        // Client 0 steals a primary client role
        ASSERT_TRUE(pCam0->forcePrimaryClient(pDisplay).isOk());

        // Join a listener
        if (listener.joinable()) {
            listener.join();
        }

        ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType), EvsEventType::MASTER_RELEASED);

        // Client 0 programs a parameter
        val0 = range.min + (std::rand() % (range.max - range.min));

        // Rounding down
        val0 = val0 - (val0 % range.step);

        if (cam0Cmds[0] == CameraParam::ABSOLUTE_FOCUS) {
            std::thread listener =
                    std::thread([&frameHandler1, &aNotification, &listening, &eventCond] {
                        listening = true;
                        eventCond.notify_all();

                        EvsEventDesc aTargetEvent;
                        aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                        aTargetEvent.payload.push_back(
                                static_cast<int32_t>(CameraParam::AUTO_FOCUS));
                        aTargetEvent.payload.push_back(0);
                        if (!frameHandler1->waitForEvent(aTargetEvent, aNotification)) {
                            LOG(WARNING) << "A timer is expired before a target event is fired.";
                        }
                    });

            // Wait until a lister starts.
            std::unique_lock<std::mutex> lock(eventLock);
            auto timer = std::chrono::system_clock::now();
            while (!listening) {
                eventCond.wait_until(lock, timer + 1s);
            }
            lock.unlock();

            // Try to turn off auto-focus
            values.clear();
            ASSERT_TRUE(pCam0->setIntParameter(CameraParam::AUTO_FOCUS, 0, &values).isOk());
            for (auto&& v : values) {
                EXPECT_EQ(v, 0);
            }

            // Join a listener
            if (listener.joinable()) {
                listener.join();
            }

            // Make sure AUTO_FOCUS is off.
            ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType),
                      EvsEventType::PARAMETER_CHANGED);
        }

        listener = std::thread(
                [&frameHandler0, &aNotification, &listening, &eventCond, &cam0Cmds, val0] {
                    listening = true;
                    eventCond.notify_all();

                    EvsEventDesc aTargetEvent;
                    aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED;
                    aTargetEvent.payload.push_back(static_cast<int32_t>(cam0Cmds[0]));
                    aTargetEvent.payload.push_back(val0);
                    if (!frameHandler0->waitForEvent(aTargetEvent, aNotification)) {
                        LOG(WARNING) << "A timer is expired before a target event is fired.";
                    }
                });

        // Wait until a lister starts.
        listening = false;
        timer = std::chrono::system_clock::now();
        lock.lock();
        while (!listening) {
            eventCond.wait_until(lock, timer + 1s);
        }
        lock.unlock();

        values.clear();
        ASSERT_TRUE(pCam0->setIntParameter(cam0Cmds[0], val0, &values).isOk());

        // Join a listener
        if (listener.joinable()) {
            listener.join();
        }
        // Verify a change notification
        ASSERT_EQ(static_cast<EvsEventType>(aNotification.aType), EvsEventType::PARAMETER_CHANGED);
        ASSERT_GE(aNotification.payload.size(), 2);
        ASSERT_EQ(static_cast<CameraParam>(aNotification.payload[0]), cam0Cmds[0]);
        for (auto&& v : values) {
            ASSERT_EQ(v, aNotification.payload[1]);
        }

        // Turn off the display (yes, before the stream stops -- it should be handled)
        ASSERT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());

        // Shut down the streamer
        frameHandler0->shutdown();
        frameHandler1->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam0).isOk());
        ASSERT_TRUE(mEnumerator->closeCamera(pCam1).isOk());
        mActiveCameras.clear();

        // Explicitly release the display
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
    }
}

/*
 * CameraUseStreamConfigToDisplay:
 * End to end test of data flowing from the camera to the display.  Similar to
 * CameraToDisplayRoundTrip test case but this case retrieves available stream
 * configurations from EVS and uses one of them to start a video stream.
 */
TEST_P(EvsAidlTest, CameraUseStreamConfigToDisplay) {
    LOG(INFO) << "Starting CameraUseStreamConfigToDisplay test";

    // Get the camera list
    loadCameraList();

    // Request available display IDs
    uint8_t targetDisplayId = 0;
    std::vector<uint8_t> displayIds;
    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
    EXPECT_GT(displayIds.size(), 0);
    targetDisplayId = displayIds[0];

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        // Request exclusive access to the EVS display
        std::shared_ptr<IEvsDisplay> pDisplay;
        ASSERT_TRUE(mEnumerator->openDisplay(targetDisplayId, &pDisplay).isOk());
        EXPECT_NE(pDisplay, nullptr);

        // choose a configuration that has a frame rate faster than minReqFps.
        Stream targetCfg = {};
        const int32_t minReqFps = 15;
        int32_t maxArea = 0;
        camera_metadata_entry_t streamCfgs;
        bool foundCfg = false;
        if (!find_camera_metadata_entry(reinterpret_cast<camera_metadata_t*>(cam.metadata.data()),
                                        ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                                        &streamCfgs)) {
            // Stream configurations are found in metadata
            RawStreamConfig* ptr = reinterpret_cast<RawStreamConfig*>(streamCfgs.data.i32);
            for (unsigned offset = 0; offset < streamCfgs.count; offset += kStreamCfgSz) {
                if (ptr->direction == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
                    if (ptr->width * ptr->height > maxArea && ptr->framerate >= minReqFps) {
                        targetCfg.width = ptr->width;
                        targetCfg.height = ptr->height;
                        targetCfg.format = static_cast<PixelFormat>(ptr->format);

                        maxArea = ptr->width * ptr->height;
                        foundCfg = true;
                    }
                }
                ++ptr;
            }
        }

        if (!foundCfg) {
            // Current EVS camera does not provide stream configurations in the
            // metadata.
            continue;
        }

        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam);

        // Set up a frame receiver object which will fire up its own thread.
        std::shared_ptr<FrameHandler> frameHandler = ndk::SharedRefBase::make<FrameHandler>(
                pCam, cam, pDisplay, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler, nullptr);

        // Activate the display
        ASSERT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());

        // Start the camera's video stream
        ASSERT_TRUE(frameHandler->startStream());

        // Wait a while to let the data flow
        static const int kSecondsToWait = 5;
        const int streamTimeMs =
                kSecondsToWait * kSecondsToMilliseconds - kMaxStreamStartMilliseconds;
        const unsigned minimumFramesExpected =
                streamTimeMs * kMinimumFramesPerSecond / kSecondsToMilliseconds;
        sleep(kSecondsToWait);
        unsigned framesReceived = 0;
        unsigned framesDisplayed = 0;
        frameHandler->getFramesCounters(&framesReceived, &framesDisplayed);
        EXPECT_EQ(framesReceived, framesDisplayed);
        EXPECT_GE(framesDisplayed, minimumFramesExpected);

        // Turn off the display (yes, before the stream stops -- it should be handled)
        ASSERT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());

        // Shut down the streamer
        frameHandler->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.clear();

        // Explicitly release the display
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
    }
}

/*
 * MultiCameraStreamUseConfig:
 * Verify that each client can start and stop video streams on the same
 * underlying camera with same configuration.
 */
TEST_P(EvsAidlTest, MultiCameraStreamUseConfig) {
    LOG(INFO) << "Starting MultiCameraStream test";

    if (mIsHwModule) {
        // This test is not for HW module implementation.
        return;
    }

    // Get the camera list
    loadCameraList();

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        // choose a configuration that has a frame rate faster than minReqFps.
        Stream targetCfg = {};
        const int32_t minReqFps = 15;
        int32_t maxArea = 0;
        camera_metadata_entry_t streamCfgs;
        bool foundCfg = false;
        if (!find_camera_metadata_entry(reinterpret_cast<camera_metadata_t*>(cam.metadata.data()),
                                        ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
                                        &streamCfgs)) {
            // Stream configurations are found in metadata
            RawStreamConfig* ptr = reinterpret_cast<RawStreamConfig*>(streamCfgs.data.i32);
            for (unsigned offset = 0; offset < streamCfgs.count; offset += kStreamCfgSz) {
                if (ptr->direction == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
                    if (ptr->width * ptr->height > maxArea && ptr->framerate >= minReqFps) {
                        targetCfg.width = ptr->width;
                        targetCfg.height = ptr->height;
                        targetCfg.format = static_cast<PixelFormat>(ptr->format);

                        maxArea = ptr->width * ptr->height;
                        foundCfg = true;
                    }
                }
                ++ptr;
            }
        }

        if (!foundCfg) {
            LOG(INFO) << "Device " << cam.id
                      << " does not provide a list of supported stream configurations, skipped";
            continue;
        }

        // Create the first camera client with a selected stream configuration.
        std::shared_ptr<IEvsCamera> pCam0;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam0).isOk());
        EXPECT_NE(pCam0, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam0);

        // Try to create the second camera client with different stream
        // configuration.
        int32_t id = targetCfg.id;
        targetCfg.id += 1;  // EVS manager sees only the stream id.
        std::shared_ptr<IEvsCamera> pCam1;
        ASSERT_FALSE(mEnumerator->openCamera(cam.id, targetCfg, &pCam1).isOk());

        // Try again with same stream configuration.
        targetCfg.id = id;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam1).isOk());
        EXPECT_NE(pCam1, nullptr);

        // Set up per-client frame receiver objects which will fire up its own thread
        std::shared_ptr<FrameHandler> frameHandler0 = ndk::SharedRefBase::make<FrameHandler>(
                pCam0, cam, nullptr, FrameHandler::eAutoReturn);
        std::shared_ptr<FrameHandler> frameHandler1 = ndk::SharedRefBase::make<FrameHandler>(
                pCam1, cam, nullptr, FrameHandler::eAutoReturn);
        EXPECT_NE(frameHandler0, nullptr);
        EXPECT_NE(frameHandler1, nullptr);

        // Start the camera's video stream via client 0
        ASSERT_TRUE(frameHandler0->startStream());
        ASSERT_TRUE(frameHandler1->startStream());

        // Ensure the stream starts
        frameHandler0->waitForFrameCount(1);
        frameHandler1->waitForFrameCount(1);

        nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC);

        // Wait a bit, then ensure both clients get at least the required minimum number of frames
        sleep(5);
        nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
        unsigned framesReceived0 = 0, framesReceived1 = 0;
        frameHandler0->getFramesCounters(&framesReceived0, nullptr);
        frameHandler1->getFramesCounters(&framesReceived1, nullptr);
        framesReceived0 = framesReceived0 - 1;  // Back out the first frame we already waited for
        framesReceived1 = framesReceived1 - 1;  // Back out the first frame we already waited for
        nsecs_t runTime = end - firstFrame;
        float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
        float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
        LOG(INFO) << "Measured camera rate " << std::scientific << framesPerSecond0 << " fps and "
                  << framesPerSecond1 << " fps";
        EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
        EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);

        // Shutdown one client
        frameHandler0->shutdown();

        // Read frame counters again
        frameHandler0->getFramesCounters(&framesReceived0, nullptr);
        frameHandler1->getFramesCounters(&framesReceived1, nullptr);

        // Wait a bit again
        sleep(5);
        unsigned framesReceivedAfterStop0 = 0, framesReceivedAfterStop1 = 0;
        frameHandler0->getFramesCounters(&framesReceivedAfterStop0, nullptr);
        frameHandler1->getFramesCounters(&framesReceivedAfterStop1, nullptr);
        EXPECT_EQ(framesReceived0, framesReceivedAfterStop0);
        EXPECT_LT(framesReceived1, framesReceivedAfterStop1);

        // Shutdown another
        frameHandler1->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam0).isOk());
        ASSERT_TRUE(mEnumerator->closeCamera(pCam1).isOk());
        mActiveCameras.clear();
    }
}

/*
 * LogicalCameraMetadata:
 * Opens logical camera reported by the enumerator and validate its metadata by
 * checking its capability and locating supporting physical camera device
 * identifiers.
 */
TEST_P(EvsAidlTest, LogicalCameraMetadata) {
    LOG(INFO) << "Starting LogicalCameraMetadata test";

    // Get the camera list
    loadCameraList();

    // Open and close each camera twice
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        auto devices = getPhysicalCameraIds(cam.id, isLogicalCam);
        if (isLogicalCam) {
            ASSERT_GE(devices.size(), 1) << "Logical camera device must have at least one physical "
                                            "camera device ID in its metadata.";
        }
    }
}

/*
 * CameraStreamExternalBuffering:
 * This is same with CameraStreamBuffering except frame buffers are allocated by
 * the test client and then imported by EVS framework.
 */
TEST_P(EvsAidlTest, CameraStreamExternalBuffering) {
    LOG(INFO) << "Starting CameraStreamExternalBuffering test";

    // Arbitrary constant (should be > 1 and not too big)
    static const unsigned int kBuffersToHold = 3;

    // Get the camera list
    loadCameraList();

    // Acquire the graphics buffer allocator
    android::GraphicBufferAllocator& alloc(android::GraphicBufferAllocator::get());
    const auto usage =
            GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;

    // Test each reported camera
    for (auto&& cam : mCameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.id, isLogicalCam);
        if (isLogicalCam) {
            LOG(INFO) << "Skip a logical device, " << cam.id;
            continue;
        }

        // Read a target resolution from the metadata
        Stream targetCfg = getFirstStreamConfiguration(
                reinterpret_cast<camera_metadata_t*>(cam.metadata.data()));
        ASSERT_GT(targetCfg.width, 0);
        ASSERT_GT(targetCfg.height, 0);

        // Allocate buffers to use
        std::vector<BufferDesc> buffers;
        buffers.resize(kBuffersToHold);
        for (auto i = 0; i < kBuffersToHold; ++i) {
            unsigned pixelsPerLine;
            buffer_handle_t memHandle = nullptr;
            android::status_t result =
                    alloc.allocate(targetCfg.width, targetCfg.height,
                                   static_cast<android::PixelFormat>(targetCfg.format),
                                   /* layerCount = */ 1, usage, &memHandle, &pixelsPerLine,
                                   /* graphicBufferId = */ 0,
                                   /* requestorName = */ "CameraStreamExternalBufferingTest");
            if (result != android::NO_ERROR) {
                LOG(ERROR) << __FUNCTION__ << " failed to allocate memory.";
                // Release previous allocated buffers
                for (auto j = 0; j < i; j++) {
                    alloc.free(::android::dupFromAidl(buffers[i].buffer.handle));
                }
                return;
            } else {
                BufferDesc buf;
                HardwareBufferDescription* pDesc =
                        reinterpret_cast<HardwareBufferDescription*>(&buf.buffer.description);
                pDesc->width = targetCfg.width;
                pDesc->height = targetCfg.height;
                pDesc->layers = 1;
                pDesc->format = targetCfg.format;
                pDesc->usage = static_cast<BufferUsage>(usage);
                pDesc->stride = pixelsPerLine;
                buf.buffer.handle = ::android::dupToAidl(memHandle);
                buf.bufferId = i;  // Unique number to identify this buffer
                buffers[i] = std::move(buf);
            }
        }

        std::shared_ptr<IEvsCamera> pCam;
        ASSERT_TRUE(mEnumerator->openCamera(cam.id, targetCfg, &pCam).isOk());
        EXPECT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        mActiveCameras.push_back(pCam);

        // Request to import buffers
        int delta = 0;
        auto status = pCam->importExternalBuffers(buffers, &delta);
        ASSERT_TRUE(status.isOk());
        EXPECT_GE(delta, kBuffersToHold);

        // Set up a frame receiver object which will fire up its own thread.
        std::shared_ptr<FrameHandler> frameHandler = ndk::SharedRefBase::make<FrameHandler>(
                pCam, cam, nullptr, FrameHandler::eNoAutoReturn);
        EXPECT_NE(frameHandler, nullptr);

        // Start the camera's video stream
        ASSERT_TRUE(frameHandler->startStream());

        // Check that the video stream stalls once we've gotten exactly the number of buffers
        // we requested since we told the frameHandler not to return them.
        sleep(1);  // 1 second should be enough for at least 5 frames to be delivered worst case
        unsigned framesReceived = 0;
        frameHandler->getFramesCounters(&framesReceived, nullptr);
        ASSERT_LE(kBuffersToHold, framesReceived) << "Stream didn't stall at expected buffer limit";

        // Give back one buffer
        EXPECT_TRUE(frameHandler->returnHeldBuffer());

        // Once we return a buffer, it shouldn't take more than 1/10 second to get a new one
        // filled since we require 10fps minimum -- but give a 10% allowance just in case.
        unsigned framesReceivedAfter = 0;
        usleep(110 * kMillisecondsToMicroseconds);
        frameHandler->getFramesCounters(&framesReceivedAfter, nullptr);
        EXPECT_EQ(framesReceived + 1, framesReceivedAfter) << "Stream should've resumed";

        // Even when the camera pointer goes out of scope, the FrameHandler object will
        // keep the stream alive unless we tell it to shutdown.
        // Also note that the FrameHandle and the Camera have a mutual circular reference, so
        // we have to break that cycle in order for either of them to get cleaned up.
        frameHandler->shutdown();

        // Explicitly release the camera
        ASSERT_TRUE(mEnumerator->closeCamera(pCam).isOk());
        mActiveCameras.clear();
        // Release buffers
        for (auto& b : buffers) {
            alloc.free(::android::dupFromAidl(b.buffer.handle));
        }
        buffers.resize(0);
    }
}

TEST_P(EvsAidlTest, DeviceStatusCallbackRegistration) {
    std::shared_ptr<IEvsEnumeratorStatusCallback> cb =
            ndk::SharedRefBase::make<DeviceStatusCallback>();
    ndk::ScopedAStatus status = mEnumerator->registerStatusCallback(cb);
    if (mIsHwModule) {
        ASSERT_TRUE(status.isOk());
    } else {
        // A callback registration may fail if a HIDL EVS HAL implementation is
        // running.
        ASSERT_TRUE(status.isOk() ||
                    status.getServiceSpecificError() == static_cast<int>(EvsResult::NOT_SUPPORTED));
    }
}

/*
 * UltrasonicsArrayOpenClean:
 * Opens each ultrasonics arrays reported by the enumerator and then explicitly closes it via a
 * call to closeUltrasonicsArray. Then repeats the test to ensure all ultrasonics arrays
 * can be reopened.
 */
TEST_P(EvsAidlTest, UltrasonicsArrayOpenClean) {
    LOG(INFO) << "Starting UltrasonicsArrayOpenClean test";

    // Get the ultrasonics array list
    loadUltrasonicsArrayList();

    // Open and close each ultrasonics array twice
    for (auto&& ultraInfo : mUltrasonicsArraysInfo) {
        for (int pass = 0; pass < 2; pass++) {
            std::shared_ptr<IEvsUltrasonicsArray> pUltrasonicsArray;
            ASSERT_TRUE(
                    mEnumerator
                            ->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId, &pUltrasonicsArray)
                            .isOk());
            EXPECT_NE(pUltrasonicsArray, nullptr);

            // Verify that this ultrasonics array self-identifies correctly
            UltrasonicsArrayDesc desc;
            ASSERT_TRUE(pUltrasonicsArray->getUltrasonicArrayInfo(&desc).isOk());
            EXPECT_EQ(ultraInfo.ultrasonicsArrayId, desc.ultrasonicsArrayId);
            LOG(DEBUG) << "Found ultrasonics array " << ultraInfo.ultrasonicsArrayId;

            // Explicitly close the ultrasonics array so resources are released right away
            ASSERT_TRUE(mEnumerator->closeUltrasonicsArray(pUltrasonicsArray).isOk());
        }
    }
}

// Starts a stream and verifies all data received is valid.
TEST_P(EvsAidlTest, UltrasonicsVerifyStreamData) {
    LOG(INFO) << "Starting UltrasonicsVerifyStreamData";

    // Get the ultrasonics array list
    loadUltrasonicsArrayList();

    // For each ultrasonics array.
    for (auto&& ultraInfo : mUltrasonicsArraysInfo) {
        LOG(DEBUG) << "Testing ultrasonics array: " << ultraInfo.ultrasonicsArrayId;

        std::shared_ptr<IEvsUltrasonicsArray> pUltrasonicsArray;
        ASSERT_TRUE(
                mEnumerator->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId, &pUltrasonicsArray)
                        .isOk());
        EXPECT_NE(pUltrasonicsArray, nullptr);

        std::shared_ptr<FrameHandlerUltrasonics> frameHandler =
                ndk::SharedRefBase::make<FrameHandlerUltrasonics>(pUltrasonicsArray);
        EXPECT_NE(frameHandler, nullptr);

        // Start stream.
        ASSERT_TRUE(pUltrasonicsArray->startStream(frameHandler).isOk());

        // Wait 5 seconds to receive frames.
        sleep(5);

        // Stop stream.
        ASSERT_TRUE(pUltrasonicsArray->stopStream().isOk());

        EXPECT_GT(frameHandler->getReceiveFramesCount(), 0);
        EXPECT_TRUE(frameHandler->areAllFramesValid());

        // Explicitly close the ultrasonics array so resources are released right away
        ASSERT_TRUE(mEnumerator->closeUltrasonicsArray(pUltrasonicsArray).isOk());
    }
}

// Sets frames in flight before and after start of stream and verfies success.
TEST_P(EvsAidlTest, UltrasonicsSetFramesInFlight) {
    LOG(INFO) << "Starting UltrasonicsSetFramesInFlight";

    // Get the ultrasonics array list
    loadUltrasonicsArrayList();

    // For each ultrasonics array.
    for (auto&& ultraInfo : mUltrasonicsArraysInfo) {
        LOG(DEBUG) << "Testing ultrasonics array: " << ultraInfo.ultrasonicsArrayId;

        std::shared_ptr<IEvsUltrasonicsArray> pUltrasonicsArray;
        ASSERT_TRUE(
                mEnumerator->openUltrasonicsArray(ultraInfo.ultrasonicsArrayId, &pUltrasonicsArray)
                        .isOk());
        EXPECT_NE(pUltrasonicsArray, nullptr);

        ASSERT_TRUE(pUltrasonicsArray->setMaxFramesInFlight(10).isOk());

        std::shared_ptr<FrameHandlerUltrasonics> frameHandler =
                ndk::SharedRefBase::make<FrameHandlerUltrasonics>(pUltrasonicsArray);
        EXPECT_NE(frameHandler, nullptr);

        // Start stream.
        ASSERT_TRUE(pUltrasonicsArray->startStream(frameHandler).isOk());
        ASSERT_TRUE(pUltrasonicsArray->setMaxFramesInFlight(5).isOk());

        // Stop stream.
        ASSERT_TRUE(pUltrasonicsArray->stopStream().isOk());

        // Explicitly close the ultrasonics array so resources are released right away
        ASSERT_TRUE(mEnumerator->closeUltrasonicsArray(pUltrasonicsArray).isOk());
    }
}

/*
 * DisplayOpen:
 * Test both clean shut down and "aggressive open" device stealing behavior.
 */
TEST_P(EvsAidlTest, DisplayOpen) {
    LOG(INFO) << "Starting DisplayOpen test";

    // Request available display IDs.
    std::vector<uint8_t> displayIds;
    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
    EXPECT_GT(displayIds.size(), 0);

    for (const auto displayId : displayIds) {
        std::shared_ptr<IEvsDisplay> pDisplay;

        // Request exclusive access to each EVS display, then let it go.
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
        ASSERT_NE(pDisplay, nullptr);

        {
            // Ask the display what its name is.
            DisplayDesc desc;
            ASSERT_TRUE(pDisplay->getDisplayInfo(&desc).isOk());
            LOG(DEBUG) << "Found display " << desc.id;
        }

        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());

        // Ensure we can reopen the display after it has been closed.
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
        ASSERT_NE(pDisplay, nullptr);

        // Open the display while its already open -- ownership should be transferred.
        std::shared_ptr<IEvsDisplay> pDisplay2;
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay2).isOk());
        ASSERT_NE(pDisplay2, nullptr);

        {
            // Ensure the old display properly reports its assassination.
            DisplayState badState;
            EXPECT_TRUE(pDisplay->getDisplayState(&badState).isOk());
            EXPECT_EQ(badState, DisplayState::DEAD);
        }

        // Close only the newest display instance -- the other should already be a zombie.
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay2).isOk());

        // Finally, validate that we can open the display after the provoked failure above.
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
        ASSERT_NE(pDisplay, nullptr);
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
    }
}

/*
 * DisplayStates:
 * Validate that display states transition as expected and can be queried from either the display
 * object itself or the owning enumerator.
 */
TEST_P(EvsAidlTest, DisplayStates) {
    using std::literals::chrono_literals::operator""ms;

    LOG(INFO) << "Starting DisplayStates test";

    // Request available display IDs.
    std::vector<uint8_t> displayIds;
    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
    EXPECT_GT(displayIds.size(), 0);

    for (const auto displayId : displayIds) {
        // Ensure the display starts in the expected state.
        {
            DisplayState state;
            EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
        }
        for (const auto displayIdToQuery : displayIds) {
            DisplayState state;
            EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
        }

        // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object.
        {
            // Request exclusive access to the EVS display.
            std::shared_ptr<IEvsDisplay> pDisplay;
            ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
            ASSERT_NE(pDisplay, nullptr);
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
            }
            for (const auto displayIdToQuery : displayIds) {
                DisplayState state;
                bool get_state_ok =
                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
                if (displayIdToQuery != displayId) {
                    EXPECT_FALSE(get_state_ok);
                } else if (get_state_ok) {
                    EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
                }
            }

            // Activate the display.
            EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
            }
            {
                DisplayState state;
                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
            }
            for (const auto displayIdToQuery : displayIds) {
                DisplayState state;
                bool get_state_ok =
                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
                if (displayIdToQuery != displayId) {
                    EXPECT_FALSE(get_state_ok);
                } else if (get_state_ok) {
                    EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
                }
            }

            // Get the output buffer we'd use to display the imagery.
            BufferDesc tgtBuffer;
            ASSERT_TRUE(pDisplay->getTargetBuffer(&tgtBuffer).isOk());

            // Send the target buffer back for display (we didn't actually fill anything).
            EXPECT_TRUE(pDisplay->returnTargetBufferForDisplay(tgtBuffer).isOk());

            // Sleep for a tenth of a second to ensure the driver has time to get the image
            // displayed.
            std::this_thread::sleep_for(100ms);
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE);
            }
            {
                DisplayState state;
                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE);
            }
            for (const auto displayIdToQuery : displayIds) {
                DisplayState state;
                bool get_state_ok =
                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
                if (displayIdToQuery != displayId) {
                    EXPECT_FALSE(get_state_ok);
                } else if (get_state_ok) {
                    EXPECT_EQ(state, DisplayState::VISIBLE);
                }
            }

            // Turn off the display.
            EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());
            std::this_thread::sleep_for(100ms);
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
            }
            {
                DisplayState state;
                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
            }
            for (const auto displayIdToQuery : displayIds) {
                DisplayState state;
                bool get_state_ok =
                        mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk();
                if (displayIdToQuery != displayId) {
                    EXPECT_FALSE(get_state_ok);
                } else if (get_state_ok) {
                    EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
                }
            }

            // Close the display.
            mEnumerator->closeDisplay(pDisplay);
        }

        // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
        // object to be destroyed, we should be back to the "not open" state.
        // NOTE:  If we want this to pass without the sleep above, we'd have to add the
        //        (now recommended) closeDisplay() call instead of relying on the smarter pointer
        //        going out of scope.  I've not done that because I want to verify that the deletion
        //        of the object does actually clean up (eventually).
        {
            DisplayState state;
            EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
        }
        for (const auto displayIdToQuery : displayIds) {
            DisplayState state;
            EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
        }
    }
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsAidlTest);
INSTANTIATE_TEST_SUITE_P(
        PerInstance, EvsAidlTest,
        testing::ValuesIn(android::getAidlHalInstanceNames(IEvsEnumerator::descriptor)),
        android::PrintInstanceNameToString);

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    ABinderProcess_setThreadPoolMaxThreadCount(1);
    ABinderProcess_startThreadPool();
    return RUN_ALL_TESTS();
}
