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

//#define LOG_NDEBUG 0
#define LOG_TAG "NativeCamera"
#include <log/log.h>

#include <chrono>
#include <cinttypes>
#include <condition_variable>
#include <map>
#include <mutex>
#include <string>
#include <vector>
#include <unistd.h>
#include <assert.h>
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <unordered_map>
#include <set>

#include <android/native_window_jni.h>

#include "camera/NdkCameraError.h"
#include "camera/NdkCameraManager.h"
#include "camera/NdkCameraMetadata.h"
#include "camera/NdkCameraDevice.h"
#include "camera/NdkCameraCaptureSession.h"
#include "media/NdkImage.h"
#include "media/NdkImageReader.h"

#define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
                            ALOGE("%s", buf);

namespace {
    const int MAX_ERROR_STRING_LEN = 512;
    char errorString[MAX_ERROR_STRING_LEN];
}

template <>
struct std::default_delete<ACameraMetadata> {
    inline void operator()(ACameraMetadata* chars) const { ACameraMetadata_free(chars); }
};

class CameraServiceListener {
  public:
    typedef std::set<std::pair<std::string, std::string>> StringPairSet;

    static void onAvailable(void* obj, const char* cameraId) {
        ALOGV("Camera %s onAvailable", cameraId);
        if (obj == nullptr) {
            return;
        }
        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnAvailableCount++;
        thiz->mAvailableMap[cameraId] = true;
        return;
    }

    static void onUnavailable(void* obj, const char* cameraId) {
        ALOGV("Camera %s onUnavailable", cameraId);
        if (obj == nullptr) {
            return;
        }
        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnUnavailableCount++;
        thiz->mAvailableMap[cameraId] = false;
        return;
    }


    static void onCameraAccessPrioritiesChanged(void* obj) {
        ALOGV("onCameraAccessPrioritiesChanged");
        if (obj == nullptr) {
            return;
        }
        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnCameraAccessPrioritiesChangedCount++;
        return;
    }

    static void onPhysicalCameraAvailable(void* obj, const char* cameraId,
            const char* physicalCameraId) {
        ALOGV("Camera %s : %s onAvailable", cameraId, physicalCameraId);
        if (obj == nullptr) {
            return;
        }
        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnPhysicalCameraAvailableCount++;
        return;
    }

    static void onPhysicalCameraUnavailable(void* obj, const char* cameraId,
            const char* physicalCameraId) {
        ALOGV("Camera %s : %s onUnavailable", cameraId, physicalCameraId);
        if (obj == nullptr) {
            return;
        }
        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mUnavailablePhysicalCameras.emplace(cameraId, physicalCameraId);
        return;
    }


    void resetCount() {
        std::lock_guard<std::mutex> lock(mMutex);
        mOnAvailableCount = 0;
        mOnUnavailableCount = 0;
        mOnCameraAccessPrioritiesChangedCount = 0;
        mOnPhysicalCameraAvailableCount = 0;
        mUnavailablePhysicalCameras.clear();
        return;
    }

    int getAvailableCount() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnAvailableCount;
    }

    int getUnavailableCount() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnUnavailableCount;
    }

    int getCameraAccessPrioritiesChangedCount() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnCameraAccessPrioritiesChangedCount;
    }

    int getPhysicalCameraAvailableCount() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnPhysicalCameraAvailableCount;
    }

    StringPairSet getUnavailablePhysicalCameras() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mUnavailablePhysicalCameras;
    }

    bool isAvailable(const char* cameraId) {
        std::lock_guard<std::mutex> lock(mMutex);
        if (mAvailableMap.count(cameraId) == 0) {
            return false;
        }
        return mAvailableMap[cameraId];
    }

  private:
    std::mutex mMutex;
    int mOnAvailableCount = 0;
    int mOnUnavailableCount = 0;
    int mOnCameraAccessPrioritiesChangedCount = 0;
    int mOnPhysicalCameraAvailableCount = 0;
    std::map<std::string, bool> mAvailableMap;
    StringPairSet mUnavailablePhysicalCameras;
};

class CameraDeviceListener {
  public:
    static void onDisconnected(void* obj, ACameraDevice* device) {
        ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
        if (obj == nullptr) {
            return;
        }
        CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnDisconnect++;
        return;
    }

    static void onError(void* obj, ACameraDevice* device, int errorCode) {
        ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
        if (obj == nullptr) {
            return;
        }
        CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnError++;
        thiz->mLatestError = errorCode;
        return;
    }

  private:
    std::mutex mMutex;
    int mOnDisconnect = 0;
    int mOnError = 0;
    int mLatestError = 0;
};

class CaptureSessionListener {

  public:
    static void onClosed(void* obj, ACameraCaptureSession *session) {
        // TODO: might want an API to query cameraId even session is closed?
        ALOGV("Session %p is closed!", session);
        if (obj == nullptr) {
            return;
        }
        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mIsClosed = true;
        thiz->mOnClosed++; // Should never > 1
    }

    static void onReady(void* obj, ACameraCaptureSession *session) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        ACameraDevice* device = nullptr;
        camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
        // There will be one onReady fired after session closed
        if (ret != ACAMERA_OK && !thiz->mIsClosed) {
            ALOGE("%s Getting camera device from session callback failed!",
                    __FUNCTION__);
            thiz->mInError = true;
        }
        ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
        thiz->mIsIdle = true;
        thiz->mOnReady++;
    }

    static void onWindowPrepared(
            void* obj, ACameraWindowType* anw, ACameraCaptureSession* session) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            ALOGE("%s ctx ptr is null ?", __FUNCTION__);
            return;
        }
        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        // Reduce the pending prepared count of anw by 1. If count is  0, remove the key.
        if(thiz->mPendingPreparedCbs.find(anw) == thiz->mPendingPreparedCbs.end()) {
            ALOGE("%s: ANW %p was not being prepared at all ?", __FUNCTION__, anw);
            return;
        }
        if (thiz->mPendingPreparedCbs[anw] == 0) {
            ALOGE("%s: ANW %p pending prepared cbs is already 0", __FUNCTION__, anw);
            return;
        }
        thiz->mPendingPreparedCbs[anw]--;
        if (thiz->mPendingPreparedCbs[anw] == 0) {
            thiz->mPendingPreparedCbs.erase(anw);
        }
    }
    static void onActive(void* obj, ACameraCaptureSession* session) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        ACameraDevice* device = nullptr;
        camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
        if (ret != ACAMERA_OK) {
            ALOGE("%s Getting camera device from session callback failed!",
                    __FUNCTION__);
            thiz->mInError = true;
        }
        ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
        thiz->mIsIdle = false;
        thiz->mOnActive;
    }
    bool gotAllPreparedCallbacksWithErrorLog() {
        std::lock_guard<std::mutex> lock(mMutex);
        bool ret = (mPendingPreparedCbs.size() == 0);
        if (!ret) {
            ALOGE("%s: mPendingPreparedCbs has the following expected callbacks", __FUNCTION__);
            for (auto pair : mPendingPreparedCbs) {
                ALOGE("%s: ANW: %p : pending callbacks %d", __FUNCTION__, pair.first, pair.second);
            }
        }
        return ret;
    }

    void incPendingPrepared(ANativeWindow *anw) {
        std::lock_guard<std::mutex> lock(mMutex);
        if ((mPendingPreparedCbs.find(anw) == mPendingPreparedCbs.end())) {
            mPendingPreparedCbs[anw] = 1;
            return;
        }
        mPendingPreparedCbs[anw]++;
    }
    bool isClosed() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mIsClosed;
    }

    bool isIdle() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mIsIdle;
    }

    bool isInError() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mInError;
    }

    int onClosedCount()  {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnClosed;
    }

    int onReadyCount()  {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnReady;
    }

    int onActiveCount()  {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnActive;
    }

    void reset() {
        std::lock_guard<std::mutex> lock(mMutex);
        mIsClosed = false;
        mIsIdle = true;
        mInError = false;
        mOnClosed = 0;
        mOnReady = 0;
        mOnActive = 0;
    }

  private:
    std::mutex mMutex;
    bool mIsClosed = false;
    bool mIsIdle = true;
    bool mInError = false; // should always stay false
    int mOnClosed = 0;
    int mOnReady = 0;
    int mOnActive = 0;
    // ANativeWindow -> # expected callbacks
    std::unordered_map<ANativeWindow *, int> mPendingPreparedCbs;
};

class CaptureResultListener {
  public:
    ~CaptureResultListener() {
        std::unique_lock<std::mutex> l(mMutex);
        clearSavedRequestsLocked();
        mCompletedFrameNumbers.clear();
        mStartedFrameNumbers.clear();
        clearFailedLostFrameNumbersLocked();
    }

    static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
            const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
        //Not used for now
    }

    static void onCaptureStartV2(void* obj, ACameraCaptureSession* /*session*/,
            const ACaptureRequest* /*request*/, int64_t /*timestamp*/, int64_t frameNumber) {
        if ((obj == nullptr) || (frameNumber < 0)) {
            return;
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);

        thiz->mStartedFrameNumbers.insert(frameNumber);
        thiz->mStartCondition.notify_one();
    }

    static void onCaptureProgressed(void* /*obj*/, ACameraCaptureSession* /*session*/,
            ACaptureRequest* /*request*/, const ACameraMetadata* /*result*/) {
        //Not used for now
    }

    static void onCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
            ACaptureRequest* request, const ACameraMetadata* result) {
        ALOGV("%s", __FUNCTION__);
        if ((obj == nullptr) || (result == nullptr)) {
            return;
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        ACameraMetadata_const_entry entry;
        auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
        if (ret != ACAMERA_OK) {
            ALOGE("Error: Sync frame number missing from result!");
            return;
        }

        ACameraMetadata* copy = ACameraMetadata_copy(result);
        ACameraMetadata_const_entry entryCopy;
        ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
        if (ret != ACAMERA_OK) {
            ALOGE("Error: Sync frame number missing from result copy!");
            return;
        }

        if (entry.data.i64[0] != entryCopy.data.i64[0]) {
            ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
                    entry.data.i64[0], entryCopy.data.i64[0]);
            return;
        }
        ACameraMetadata_free(copy);

        if (thiz->mSaveCompletedRequests) {
            thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
        }

        thiz->mCompletedFrameNumbers.insert(entry.data.i64[0]);
        thiz->mResultCondition.notify_one();
    }

    static void onLogicalCameraCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
            ACaptureRequest* request, const ACameraMetadata* result,
            size_t physicalResultCount, const char** physicalCameraIds,
            const ACameraMetadata** physicalResults) {
        ALOGV("%s", __FUNCTION__);
        if ((obj == nullptr) || (result == nullptr)) {
            return;
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        ACameraMetadata_const_entry entry;
        auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
        if (ret != ACAMERA_OK) {
            ALOGE("Error: Sync frame number missing from result!");
            return;
        }

        ACameraMetadata* copy = ACameraMetadata_copy(result);
        ACameraMetadata_const_entry entryCopy;
        ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
        if (ret != ACAMERA_OK) {
            ALOGE("Error: Sync frame number missing from result copy!");
            return;
        }

        if (entry.data.i64[0] != entryCopy.data.i64[0]) {
            ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
                    entry.data.i64[0], entryCopy.data.i64[0]);
            return;
        }

        if (thiz->mRegisteredPhysicalIds.size() != physicalResultCount) {
            ALOGE("Error: Number of registered physical camera Ids %zu is different than received"
                    " physical camera Ids %zu", thiz->mRegisteredPhysicalIds.size(),
                    physicalResultCount);
            return;
        }
        for (size_t i = 0; i < physicalResultCount; i++) {
            if (physicalCameraIds[i] == nullptr) {
                ALOGE("Error: Invalid physical camera id in capture result");
                return;
            }
            if (physicalResults[i] == nullptr) {
                ALOGE("Error: Invalid physical camera metadata in capture result");
                return;
            }
            ACameraMetadata_const_entry physicalEntry;
            auto ret = ACameraMetadata_getConstEntry(physicalResults[i], ACAMERA_SYNC_FRAME_NUMBER,
                    &physicalEntry);
            if (ret != ACAMERA_OK) {
                ALOGE("Error: Sync frame number missing from physical camera result metadata!");
                return;
            }
            if (physicalEntry.data.i64[0] != entryCopy.data.i64[0]) {
                ALOGE("Error: Physical camera sync frame number %" PRId64
                        " mismatch result copy %" PRId64,
                        physicalEntry.data.i64[0], entryCopy.data.i64[0]);
                return;
            }

            auto foundId = std::find(thiz->mRegisteredPhysicalIds.begin(),
                    thiz->mRegisteredPhysicalIds.end(), physicalCameraIds[i]);
            if (foundId == thiz->mRegisteredPhysicalIds.end()) {
                ALOGE("Error: Returned physical camera Id %s is not registered",
                        physicalCameraIds[i]);
                return;
            }
        }
        ACameraMetadata_free(copy);

        if (thiz->mSaveCompletedRequests) {
            thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
        }

        thiz->mCompletedFrameNumbers.insert(entry.data.i64[0]);
        thiz->mResultCondition.notify_one();
    }

    static void onCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
            ACaptureRequest* /*request*/, ACameraCaptureFailure* failure) {
        ALOGV("%s", __FUNCTION__);
        if ((obj == nullptr) || (failure == nullptr)) {
            return;
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mFailedFrameNumbers.insert(failure->frameNumber);
        thiz->mResultCondition.notify_one();
    }

    static void onLogicalCameraCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
            ACaptureRequest* /*request*/, ALogicalCameraCaptureFailure* failure) {
        ALOGV("%s", __FUNCTION__);
        if ((obj == nullptr) || (failure == nullptr)) {
            return;
        }
        if (failure->physicalCameraId != nullptr) {
            ALOGV("%s: physicalCameraId: %s", __FUNCTION__, failure->physicalCameraId);
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mFailedFrameNumbers.insert(failure->captureFailure.frameNumber);
        thiz->mResultCondition.notify_one();
    }

    static void onCaptureSequenceCompleted(void* obj, ACameraCaptureSession* /*session*/,
            int sequenceId, int64_t frameNumber) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mLastSequenceIdCompleted = sequenceId;
        thiz->mLastSequenceFrameNumber = frameNumber;
        thiz->mResultCondition.notify_one();
    }

    static void onCaptureSequenceAborted(void* /*obj*/, ACameraCaptureSession* /*session*/,
            int /*sequenceId*/) {
        //Not used for now
    }

    static void onCaptureBufferLost(void* obj, ACameraCaptureSession* /*session*/,
            ACaptureRequest* /*request*/, ANativeWindow* /*window*/, int64_t frameNumber) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mBufferLostFrameNumbers.insert(frameNumber);
        thiz->mResultCondition.notify_one();
    }

    int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
        int64_t ret = -1;
        std::unique_lock<std::mutex> l(mMutex);

        while (mLastSequenceIdCompleted != sequenceId) {
            auto timeout = std::chrono::system_clock::now() +
                           std::chrono::seconds(timeoutSec);
            if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
                break;
            }
        }

        if (mLastSequenceIdCompleted == sequenceId) {
            ret = mLastSequenceFrameNumber;
        }

        return ret;
    }

    bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
        bool ret = false;
        std::unique_lock<std::mutex> l(mMutex);

        while ((mCompletedFrameNumbers.find(frameNumber) == mCompletedFrameNumbers.end()) &&
                !checkForFailureOrLossLocked(frameNumber)) {
            auto timeout = std::chrono::system_clock::now() +
                           std::chrono::seconds(timeoutSec);
            if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
                break;
            }
        }

        if ((mCompletedFrameNumbers.find(frameNumber) != mCompletedFrameNumbers.end()) ||
                checkForFailureOrLossLocked(frameNumber)) {
            ret = true;
        }

        return ret;
    }

    bool waitForFrameNumberStarted(int64_t frameNumber, uint32_t timeoutSec) {
        bool ret = false;
        std::unique_lock<std::mutex> l(mMutex);

        while ((mStartedFrameNumbers.find(frameNumber) == mStartedFrameNumbers.end())) {
            auto timeout = std::chrono::system_clock::now() +
                           std::chrono::seconds(timeoutSec);
            if (std::cv_status::timeout == mStartCondition.wait_until(l, timeout)) {
                break;
            }
        }

        if ((mStartedFrameNumbers.find(frameNumber) != mStartedFrameNumbers.end())) {
            ret = true;
        }

        return ret;
    }

    void setRequestSave(bool enable) {
        std::unique_lock<std::mutex> l(mMutex);
        if (!enable) {
            clearSavedRequestsLocked();
        }
        mSaveCompletedRequests = enable;
    }

    // The lifecycle of returned ACaptureRequest* is still managed by CaptureResultListener
    void getCompletedRequests(std::vector<ACaptureRequest*>* out) {
        std::unique_lock<std::mutex> l(mMutex);
        *out = mCompletedRequests;
    }

    void registerPhysicalResults(size_t physicalIdCnt, const char*const* physicalOutputs) {
        std::unique_lock<std::mutex> l(mMutex);
        mRegisteredPhysicalIds.clear();
        for (size_t i = 0; i < physicalIdCnt; i++) {
            mRegisteredPhysicalIds.push_back(physicalOutputs[i]);
        }
    }

    bool checkForFailureOrLoss(int64_t frameNumber) {
        std::lock_guard<std::mutex> lock(mMutex);
        return checkForFailureOrLossLocked(frameNumber);
    }

    void reset() {
        std::lock_guard<std::mutex> lock(mMutex);
        mLastSequenceIdCompleted = -1;
        mLastSequenceFrameNumber = -1;
        mSaveCompletedRequests = false;
        clearSavedRequestsLocked();
        mCompletedFrameNumbers.clear();
        clearFailedLostFrameNumbersLocked();
    }

  private:
    std::mutex mMutex;
    std::condition_variable mResultCondition;
    std::condition_variable mStartCondition;
    int mLastSequenceIdCompleted = -1;
    int64_t mLastSequenceFrameNumber = -1;
    std::set<int64_t> mCompletedFrameNumbers;
    std::set<int64_t> mStartedFrameNumbers;
    std::set<int64_t> mFailedFrameNumbers, mBufferLostFrameNumbers;
    bool    mSaveCompletedRequests = false;
    std::vector<ACaptureRequest*> mCompletedRequests;
    // Registered physical camera Ids that are being requested upon.
    std::vector<std::string> mRegisteredPhysicalIds;

    void clearSavedRequestsLocked() {
        for (ACaptureRequest* req : mCompletedRequests) {
            ACaptureRequest_free(req);
        }
        mCompletedRequests.clear();
    }

    void clearFailedLostFrameNumbersLocked() {
        mFailedFrameNumbers.clear();
        mBufferLostFrameNumbers.clear();
    }

    bool checkForFailureOrLossLocked(int64_t frameNumber) {
        return (mFailedFrameNumbers.find(frameNumber) != mFailedFrameNumbers.end()) ||
                (mBufferLostFrameNumbers.find(frameNumber) != mBufferLostFrameNumbers.end());
    }
};

class ImageReaderListener {
  public:
    ImageReaderListener() {
        mBufferTs.insert(mLastBufferTs);
    }

    // count, acquire, validate, and delete AImage when a new image is available
    static void validateImageCb(void* obj, AImageReader* reader) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnImageAvailableCount++;

        AImage* img = nullptr;
        media_status_t ret = AImageReader_acquireNextImage(reader, &img);
        if (ret != AMEDIA_OK || img == nullptr) {
            ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
                    __FUNCTION__, reader, ret, img);
            return;
        }

        // TODO: validate image content
        int32_t format = -1;
        ret = AImage_getFormat(img, &format);
        if (ret != AMEDIA_OK || format == -1) {
            ALOGE("%s: get format for image %p failed! ret: %d, format %d",
                    __FUNCTION__, img, ret, format);
        }

        // Save jpeg to SD card
        if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
            int32_t numPlanes = 0;
            ret = AImage_getNumberOfPlanes(img, &numPlanes);
            if (ret != AMEDIA_OK || numPlanes != 1) {
                ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
                        __FUNCTION__, img, ret, numPlanes);
                AImage_delete(img);
                return;
            }

            int32_t width = -1, height = -1;
            ret = AImage_getWidth(img, &width);
            if (ret != AMEDIA_OK || width <= 0) {
                ALOGE("%s: get width for image %p failed! ret: %d, width %d",
                        __FUNCTION__, img, ret, width);
                AImage_delete(img);
                return;
            }

            ret = AImage_getHeight(img, &height);
            if (ret != AMEDIA_OK || height <= 0) {
                ALOGE("%s: get height for image %p failed! ret: %d, height %d",
                        __FUNCTION__, img, ret, height);
                AImage_delete(img);
                return;
            }

            uint8_t* data = nullptr;
            int dataLength = 0;
            ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
            if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
                ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
                        __FUNCTION__, img, ret, data, dataLength);
                AImage_delete(img);
                return;
            }

#if 0
            char dumpFilePath[512];
            sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
            ALOGI("Writing jpeg file to %s", dumpFilePath);
            FILE* file = fopen(dumpFilePath,"w+");

            if (file != nullptr) {
                fwrite(data, 1, dataLength, file);
                fflush(file);
                fclose(file);
            }
#endif
        }

        AImage_delete(img);
    }

    // count, acquire image but not delete the image
    static void acquireImageCb(void* obj, AImageReader* reader) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);
        thiz->mOnImageAvailableCount++;

        // Acquire, but not closing.
        AImage* img = nullptr;
        media_status_t ret = AImageReader_acquireNextImage(reader, &img);
        if (ret != AMEDIA_OK || img == nullptr) {
            ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
                    __FUNCTION__, reader, ret, img);
            return;
        }
        return;
    }

    int onImageAvailableCount() {
        std::lock_guard<std::mutex> lock(mMutex);
        return mOnImageAvailableCount;
    }

    void setDumpFilePathBase(const char* path) {
        std::lock_guard<std::mutex> lock(mMutex);
        mDumpFilePathBase = path;
    }

    // acquire image, query the corresponding timestamp but not delete the image
    static void signalImageCb(void* obj, AImageReader* reader) {
        ALOGV("%s", __FUNCTION__);
        if (obj == nullptr) {
            return;
        }
        ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
        std::lock_guard<std::mutex> lock(thiz->mMutex);

        AImage* img = nullptr;
        media_status_t ret = AImageReader_acquireNextImage(reader, &img);
        if (ret != AMEDIA_OK || img == nullptr) {
            ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
                    __FUNCTION__, reader, ret, img);
            thiz->mBufferCondition.notify_one();
            return;
        }

        int64_t currentTs = -1;
        ret = AImage_getTimestamp(img, &currentTs);
        if (ret != AMEDIA_OK || currentTs == -1) {
            ALOGE("%s: acquire image from reader %p failed! ret: %d", __FUNCTION__, reader, ret);
            AImage_delete(img);
            thiz->mBufferCondition.notify_one();
            return;
        }

        thiz->mBufferTs.insert(currentTs);
        thiz->mBufferCondition.notify_one();
        return;
    }

    bool waitForNextBuffer(uint32_t timeoutSec) {
        bool ret = false;
        std::unique_lock<std::mutex> l(mMutex);

        auto it = mBufferTs.find(mLastBufferTs);
        if (it == mBufferTs.end()) {
            ALOGE("%s: Last buffer timestamp: %" PRId64 " not found!", __FUNCTION__, mLastBufferTs);
            return false;
        }
        it++;

        if (it == mBufferTs.end()) {
            auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(timeoutSec);
            if (std::cv_status::no_timeout == mBufferCondition.wait_until(l, timeout)) {
                it = mBufferTs.find(mLastBufferTs);
                it++;
            }
        }

        if (it != mBufferTs.end()) {
            mLastBufferTs = *it;
            ret = true;
        }

        return ret;
    }

  private:
    // TODO: add mReader to make sure each listener is associated to one reader?
    std::mutex mMutex;
    int mOnImageAvailableCount = 0;
    const char* mDumpFilePathBase = nullptr;
    std::condition_variable mBufferCondition;
    int64_t mLastBufferTs = -1;
    std::set<int64_t> mBufferTs;
};

class StaticInfo {
  public:
    explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}

    bool isColorOutputSupported() {
        return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
    }

    bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
        ACameraMetadata_const_entry entry;
        ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
        for (uint32_t i = 0; i < entry.count; i++) {
            if (entry.data.u8[i] == cap) {
                return true;
            }
        }
        return false;
    }

    int64_t getMinFrameDurationFor(int64_t format, int64_t width, int64_t height) {
        int32_t minFrameDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
                ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS :
                (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
                ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS :
                ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
        return getDurationFor(minFrameDurationTag, format, width, height);
    }

    int64_t getStallDurationFor(int64_t format, int64_t width, int64_t height) {
        int32_t stallDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
                ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS : (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
                ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS :
                ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS;
        return getDurationFor(stallDurationTag, format, width, height);
    }

    bool getMaxSizeForFormat(int32_t format, int32_t *width, int32_t *height) {
        ACameraMetadata_const_entry entry;

        int32_t streamConfigTag, streamConfigOutputTag;
        switch (format) {
            case AIMAGE_FORMAT_HEIC:
                streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
                streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
                break;
            case AIMAGE_FORMAT_DEPTH_JPEG:
                streamConfigTag = ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS;
                streamConfigOutputTag =
                        ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT;
                break;
            case AIMAGE_FORMAT_JPEG:
            case AIMAGE_FORMAT_Y8:
            default:
                streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
                streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
                break;
        }

        bool supported = false;
        camera_status_t status = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
        if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
            return supported;
        }

       int32_t w = 0, h = 0;
        for (uint32_t i = 0; i < entry.count; i += 4) {
            if (entry.data.i32[i] == format &&
                    entry.data.i32[i+3] == streamConfigOutputTag &&
                    entry.data.i32[i+1] * entry.data.i32[i+2] > w * h) {
                w = entry.data.i32[i+1];
                h = entry.data.i32[i+2];
                supported = true;
            }
        }

        if (supported) {
            *width = w;
            *height = h;
        }
        return supported;
    }

    bool isSizeSupportedForFormat(int32_t format, int32_t width, int32_t height) {
        ACameraMetadata_const_entry entry;

        int32_t streamConfigTag, streamConfigOutputTag;
        switch (format) {
            case AIMAGE_FORMAT_HEIC:
                streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
                streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
                break;
            case AIMAGE_FORMAT_JPEG:
            case AIMAGE_FORMAT_Y8:
            default:
                streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
                streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
                break;
        }

        auto ret = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
        if (ret != ACAMERA_OK) {
            return false;
        }
        for (uint32_t i = 0; i < entry.count; i += 4) {
            if (entry.data.i32[i] == format &&
                    entry.data.i32[i+3] == streamConfigOutputTag &&
                    entry.data.i32[i+1] == width &&
                    entry.data.i32[i+2] == height) {
                return true;
            }
        }
        return false;
    }
  private:
    int64_t getDurationFor(uint32_t tag, int64_t format, int64_t width, int64_t height) {
        if (tag != ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS &&
                tag != ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS &&
                tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS &&
                tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS &&
                tag != ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS &&
                tag != ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS &&
                tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS &&
                tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS) {
            return -1;
        }
        ACameraMetadata_const_entry entry;
        ACameraMetadata_getConstEntry(mChars, tag, &entry);
        for (uint32_t i = 0; i < entry.count; i += 4) {
            if (entry.data.i64[i] == format &&
                    entry.data.i64[i+1] == width &&
                    entry.data.i64[i+2] == height) {
                return entry.data.i64[i+3];
            }
        }
        return -1;
    }
    const ACameraMetadata* mChars;
};

class PreviewTestCase {
  public:
    ~PreviewTestCase() {
        resetCamera();
        deInit();
        if (mCameraManager) {
            ACameraManager_delete(mCameraManager);
            mCameraManager = nullptr;
        }
    }

    PreviewTestCase() {
        // create is guaranteed to succeed;
        createManager();
    }

    // Free all resources except camera manager
    void resetCamera() {
        mSessionListener.reset();
        mResultListener.reset();
        if (mSession) {
            ACameraCaptureSession_close(mSession);
            mSession = nullptr;
        }
        if (mDevice) {
            ACameraDevice_close(mDevice);
            mDevice = nullptr;
        }
        if (mImgReader) {
            AImageReader_delete(mImgReader);
            // No need to call ANativeWindow_release on imageReaderAnw
            mImgReaderAnw = nullptr;
            mImgReader = nullptr;
        }
        if (mPreviewAnw) {
            ANativeWindow_release(mPreviewAnw);
            mPreviewAnw = nullptr;
        }
        if (mOutputs) {
            ACaptureSessionOutputContainer_free(mOutputs);
            mOutputs = nullptr;
        }
        if (mPreviewOutput) {
            ACaptureSessionOutput_free(mPreviewOutput);
            mPreviewOutput = nullptr;
        }
        if (mImgReaderOutput) {
            ACaptureSessionOutput_free(mImgReaderOutput);
            mImgReaderOutput = nullptr;
        }
        if (mPreviewRequest) {
            ACaptureRequest_free(mPreviewRequest);
            mPreviewRequest = nullptr;
        }
        if (mStillRequest) {
            ACaptureRequest_free(mStillRequest);
            mStillRequest = nullptr;
        }
        if (mReqPreviewOutput) {
            ACameraOutputTarget_free(mReqPreviewOutput);
            mReqPreviewOutput = nullptr;
        }
        if (mReqImgReaderOutput) {
            ACameraOutputTarget_free(mReqImgReaderOutput);
            mReqImgReaderOutput = nullptr;
        }

        mImgReaderInited = false;
        mPreviewInited = false;
    }

    camera_status_t initWithErrorLog() {
        return initWithErrorLog(nullptr /*env*/, nullptr /*jOverrideCameraId*/);
    }

    camera_status_t initWithErrorLog(JNIEnv* env, jstring jOverrideCameraId) {
        camera_status_t ret = ACameraManager_getCameraIdList(
                mCameraManager, &mCameraIdList);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
            return ret;
        }

        if (env != nullptr && jOverrideCameraId != nullptr) {
            mOverrideCameraId = env->GetStringUTFChars(jOverrideCameraId, 0);
        }
        ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
            return ret;
        }
        mMgrInited = true;
        mJOverrideCameraId = jOverrideCameraId;
        mJNIEnv = env;
        return ACAMERA_OK;
    }

    camera_status_t deInit () {
        if (!mMgrInited) {
            return ACAMERA_OK;
        }

        camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
                mCameraManager, &mServiceCb);
        if (ret != ACAMERA_OK) {
            ALOGE("Unregister availability callback failed: ret %d", ret);
            return ret;
        }

        if (mCameraIdList) {
            ACameraManager_deleteCameraIdList(mCameraIdList);
            mCameraIdList = nullptr;
        }
        mMgrInited = false;
        if (mOverrideCameraId != nullptr && mJNIEnv != nullptr) {
            mJNIEnv->ReleaseStringUTFChars(mJOverrideCameraId, mOverrideCameraId);
            mOverrideCameraId = nullptr;
            mJOverrideCameraId = nullptr;
            mJNIEnv = nullptr;
        }
        return ACAMERA_OK;
    }

    int getNumCameras() {
        if (!mMgrInited || !mCameraIdList) {
            ALOGE("%s CameraManager not inited yet.", __FUNCTION__);
            return -1;
        }
        if (mOverrideCameraId != nullptr) {
            return 1;
        }
        return mCameraIdList->numCameras;
    }

    const char* getCameraId(int idx) {
        if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
            return nullptr;
        }
        if (mOverrideCameraId != nullptr) {
            if (idx >= 1) {
                return nullptr;
            } else {
                return mOverrideCameraId;
            }
        }
        return mCameraIdList->cameraIds[idx];
    }

    // Caller is responsible to free returned characteristics metadata
    ACameraMetadata* getCameraChars(int idx) {
        if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
            return nullptr;
        }
        const char* cameraId = mCameraIdList->cameraIds[idx];
        if (mOverrideCameraId != nullptr) {
            if (idx >= 1) {
                return nullptr;
            } else {
                cameraId = mOverrideCameraId;
            }
        }

        ACameraMetadata* chars;
        camera_status_t ret = ACameraManager_getCameraCharacteristics(
                mCameraManager, cameraId, &chars);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
            return nullptr;
        }
        return chars;
    }

    // Caller is responsible to free returned characteristics metadata.
    ACameraMetadata* getCameraChars(const char* id) {
        if (!mMgrInited || id == nullptr) {
            return nullptr;
        }

        ACameraMetadata* chars;
        camera_status_t ret = ACameraManager_getCameraCharacteristics(mCameraManager, id, &chars);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
            return nullptr;
        }
        return chars;
    }

    camera_status_t updateOutput(JNIEnv* env, ACaptureSessionOutput *output) {
        if (mSession == nullptr) {
            ALOGE("Testcase cannot update output configuration session %p",
                    mSession);
            return ACAMERA_ERROR_UNKNOWN;
        }

        return ACameraCaptureSession_updateSharedOutput(mSession, output);
    }

    camera_status_t openCamera(const char* cameraId) {
        if (mDevice) {
            ALOGE("Cannot open camera before closing previously open one");
            return ACAMERA_ERROR_INVALID_PARAMETER;
        }
        mCameraId = cameraId;
        return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
    }

    camera_status_t closeCamera() {
        camera_status_t ret = ACameraDevice_close(mDevice);
        mDevice = nullptr;
        return ret;
    }

    bool isCameraAvailable(const char* cameraId) {
        if (!mMgrInited) {
            ALOGE("Camera service listener has not been registered!");
        }
        return mServiceListener.isAvailable(cameraId);
    }

    media_status_t initImageReaderWithErrorLog(
            int32_t width, int32_t height, int32_t format, int32_t maxImages,
            AImageReader_ImageListener* listener) {
        if (mImgReader || mImgReaderAnw) {
            LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
            return AMEDIA_ERROR_UNKNOWN;
        }

        media_status_t ret = initImageReaderWithErrorLog(
                width, height, format, maxImages, listener, &mImgReader,
                &mImgReaderAnw);
        if (ret != AMEDIA_OK) {
            return ret;
        }

        mImgReaderInited = true;
        return AMEDIA_OK;
    }

    media_status_t initImageReaderWithErrorLog(
            int32_t width, int32_t height, int32_t format, int32_t maxImages,
            AImageReader_ImageListener* listener, AImageReader **imgReader,
            ANativeWindow **imgReaderAnw) {

        media_status_t ret = AImageReader_new(
                width, height, format,
                maxImages, imgReader);
        if (ret != AMEDIA_OK) {
            LOG_ERROR(errorString, "Create image reader. ret %d", ret);
            return ret;
        }
        if (*imgReader == nullptr) {
            LOG_ERROR(errorString, "null image reader created");
            return AMEDIA_ERROR_UNKNOWN;
        }

        ret = AImageReader_setImageListener(*imgReader, listener);
        if (ret != AMEDIA_OK) {
            LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
            return ret;
        }

        ret = AImageReader_getWindow(*imgReader, imgReaderAnw);
        if (ret != AMEDIA_OK) {
            LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
            return ret;
        }
        if (*imgReaderAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from AImageReader!");
            return AMEDIA_ERROR_UNKNOWN;
        }
        return AMEDIA_OK;
    }

    ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
        if (mPreviewAnw) {
            ALOGE("Cannot init preview twice!");
            return nullptr;
        }
        mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
        mPreviewInited = true;
        return mPreviewAnw;
    }

    camera_status_t createCaptureSessionWithLog(bool isPreviewShared = false,
            ACaptureRequest *sessionParameters = nullptr) {
        std::vector<ACaptureSessionOutput*> extraOutputs;
        return createCaptureSessionWithLog(extraOutputs, isPreviewShared, sessionParameters);
    }

    camera_status_t createCaptureSessionOutputContainer(
            const std::vector<ACaptureSessionOutput*> extraOutputs,
            ACaptureSessionOutputContainer** outputs,
            bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr) {
        if (!mMgrInited || (!mImgReaderInited && !mPreviewInited) || !outputs) {
            LOG_ERROR(errorString, "Cannot create session output container. mgrInit %d "
                    "readerInit %d previewInit %d outputs %p",
                    mMgrInited, mImgReaderInited, mPreviewInited, outputs);
            return ACAMERA_ERROR_UNKNOWN;
        }

        camera_status_t ret = ACaptureSessionOutputContainer_create(outputs);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
            return ret;
        }

        if (mImgReaderInited) {
            ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
            if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
                LOG_ERROR(errorString,
                        "Session image reader output create fail! ret %d output %p",
                        ret, mImgReaderOutput);
                if (ret == ACAMERA_OK) {
                    ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
                }
                return ret;
            }

            ret = ACaptureSessionOutputContainer_add(*outputs, mImgReaderOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
                return ret;
            }
        }

        for (auto extraOutput : extraOutputs) {
            ret = ACaptureSessionOutputContainer_add(*outputs, extraOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
                return ret;
            }
        }

        if (mPreviewInited) {
            if (isPreviewShared) {
                ret = ACaptureSessionSharedOutput_create(mPreviewAnw, &mPreviewOutput);
            } else {
                ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
            }
            if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
                LOG_ERROR(errorString,
                        "Session preview output create fail! ret %d output %p",
                        ret, mPreviewOutput);
                if (ret == ACAMERA_OK) {
                    ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
                }
                return ret;
            }

            ret = ACaptureSessionOutputContainer_add(*outputs, mPreviewOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Session preview output add failed! ret %d", ret);
                return ret;
            }
        }
        return ret;
    }

    camera_status_t createCaptureSessionWithLog(
            const std::vector<ACaptureSessionOutput*> extraOutputs,
            bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr,
            bool sessionConfigurationDefault = true) {
        if (mSession) {
            LOG_ERROR(errorString, "Cannot create session before closing existing one");
            return ACAMERA_ERROR_UNKNOWN;
        }

        camera_status_t ret = createCaptureSessionOutputContainer(
                extraOutputs, &mOutputs, isPreviewShared, sessionParameters);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Failed to create session output container! ret %d", ret);
            return ret;
        }

        ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
        if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION &&
                ret != ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
            LOG_ERROR(errorString, "isSessionConfigurationSupported must return either OK "
                    ", UNSUPPORTED_OPERATION, or STREAM_CONFIGURE_FAIL, but returns %d", ret);
            return ret;
        }

        // If session configuration is not supported by default, return early
        // when camera device doesn't explicitly claim support.
        if (ret != ACAMERA_OK && !sessionConfigurationDefault) {
            return ret;
        }

        ret = ACameraDevice_createCaptureSessionWithSessionParameters(
                mDevice, mOutputs, sessionParameters, &mSessionCb, &mSession);
        if (ret != ACAMERA_OK || mSession == nullptr) {
            LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
                    mCameraId, ret, mSession);
            if (ret == ACAMERA_OK) {
                ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
            }
            return ret;
        }

        return ACAMERA_OK;
    }

    camera_status_t prepareWindow(ANativeWindow *window) {
        if (mSession == nullptr) {
            ALOGE("%s: Called when session hasn't been configured", __FUNCTION__);
            return ACAMERA_ERROR_INVALID_OPERATION;
        }
        mSessionListener.incPendingPrepared(window);
        return ACameraCaptureSession_prepareWindow(mSession, window);
    }

    camera_status_t setWindowPreparedCallback() {
        if (mSession == nullptr) {
            ALOGE("%s: Called when session hasn't been configured", __FUNCTION__);
            return ACAMERA_ERROR_INVALID_OPERATION;
        }
        return ACameraCaptureSession_setWindowPreparedCallback(mSession, &mSessionListener,
                                                               mPreparedCb);
    }

    bool gotAllPreparedCallbacksWithErrorLog() {
        return mSessionListener.gotAllPreparedCallbacksWithErrorLog();
    }
    void closeSession() {
        if (mSession != nullptr) {
            ACameraCaptureSession_close(mSession);
        }
        if (mOutputs) {
            ACaptureSessionOutputContainer_free(mOutputs);
            mOutputs = nullptr;
        }
        if (mPreviewOutput) {
            ACaptureSessionOutput_free(mPreviewOutput);
            mPreviewOutput = nullptr;
        }
        if (mImgReaderOutput) {
            ACaptureSessionOutput_free(mImgReaderOutput);
            mImgReaderOutput = nullptr;
        }
        mSession = nullptr;
    }

    camera_status_t createRequestsWithErrorLog() {
        std::vector<ACameraOutputTarget*> extraOutputs;
        return createRequestsWithErrorLog(extraOutputs);
    }

    camera_status_t createRequestsWithErrorLog(
                const std::vector<ACameraOutputTarget*> extraOutputs,
                const ACameraIdList* physicalCameraIdList = nullptr) {
        if (mPreviewRequest || mStillRequest) {
            LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
            return ACAMERA_ERROR_UNKNOWN;
        }

        if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
            LOG_ERROR(errorString,
                    "Cannot create request. device %p previewInit %d readeInit %d",
                    mDevice, mPreviewInited, mImgReaderInited);
            return ACAMERA_ERROR_UNKNOWN;
        }

        camera_status_t ret;
        bool usePhysicalSettings = (physicalCameraIdList != nullptr);
        if (mPreviewInited) {
            if (!usePhysicalSettings) {
                ret = ACameraDevice_createCaptureRequest(
                        mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
            } else {
                ret = ACameraDevice_createCaptureRequest_withPhysicalIds(
                        mDevice, TEMPLATE_PREVIEW, physicalCameraIdList, &mPreviewRequest);
            }
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
                        mCameraId, ret);
                return ret;
            }

            if (usePhysicalSettings) {
                for (int i = 0; i < physicalCameraIdList->numCameras; i++) {
                    // Check physical camera specific metadata functions.
                    uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
                    ret = ACaptureRequest_setEntry_physicalCamera_u8(mPreviewRequest,
                            physicalCameraIdList->cameraIds[i], ACAMERA_CONTROL_AE_MODE,
                            1 /*count*/, &aeMode);
                    if (ret != ACAMERA_OK) {
                        LOG_ERROR(errorString,
                            "Error: Camera %s update AE mode key fail. ret %d",
                            physicalCameraIdList->cameraIds[i], ret);
                        return ret;
                    }

                    ACameraMetadata_const_entry entry;
                    ret = ACaptureRequest_getConstEntry_physicalCamera(mPreviewRequest,
                                physicalCameraIdList->cameraIds[i],
                                ACAMERA_CONTROL_AE_MODE, &entry);
                    if (ret != ACAMERA_OK) {
                        LOG_ERROR(errorString, "Get AE mode key for physicalCamera %s failed."
                                " ret %d", physicalCameraIdList->cameraIds[i], ret);
                        return ret;
                    }
                    if (entry.data.u8[0] != aeMode) {
                        LOG_ERROR(errorString,
                            "Error: AE mode key is not updated. expect %d but get %d",
                            aeMode, entry.data.u8[0]);
                        return ACAMERA_ERROR_UNKNOWN;
                    }
                }
            }

            ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString,
                        "Camera %s create request preview output target failed. ret %d",
                        mCameraId, ret);
                return ret;
            }

            ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
                        mCameraId, ret);
                return ret;
            }

            // Add extraOutputs to the request
            for (auto extraOutput : extraOutputs) {
                ret = ACaptureRequest_addTarget(mPreviewRequest, extraOutput);
                if (ret != ACAMERA_OK) {
                    LOG_ERROR(errorString, "Camera %s add extra request output failed. ret %d",
                            mCameraId, ret);
                    return ret;
                }
            }
        } else {
            ALOGI("Preview not inited. Will not create preview request!");
        }

        if (mImgReaderInited) {
            ret = ACameraDevice_createCaptureRequest(
                    mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
                        mCameraId, ret);
                return ret;
            }

            ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString,
                        "Camera %s create request reader output target failed. ret %d",
                        mCameraId, ret);
                return ret;
            }

            ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
                        mCameraId, ret);
                return ret;
            }

            if (mPreviewInited) {
                ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
                if (ret != ACAMERA_OK) {
                    LOG_ERROR(errorString,
                            "Camera %s add still request preview output failed. ret %d",
                            mCameraId, ret);
                    return ret;
                }
            }
        } else {
            ALOGI("AImageReader not inited. Will not create still request!");
        }

        return ACAMERA_OK;
    }

    // The output ACaptureRequest* is still managed by testcase class
    camera_status_t getStillRequest(ACaptureRequest** out) {
        if (mStillRequest == nullptr) {
            ALOGE("Camera %s Still capture request hasn't been created", mCameraId);
            return ACAMERA_ERROR_INVALID_PARAMETER;
        }
        *out = mStillRequest;
        return ACAMERA_OK;
    }

    camera_status_t getPreviewRequest(ACaptureRequest** out) {
        if (mPreviewRequest == nullptr) {
            ALOGE("Camera %s Preview capture request hasn't been created", mCameraId);
            return ACAMERA_ERROR_INVALID_PARAMETER;
        }
        *out = mPreviewRequest;
        return ACAMERA_OK;
    }

    camera_status_t startPreview(int *sequenceId = nullptr, size_t physicalIdCnt = 0,
            const char*const* extraPhysicalOutputs = nullptr, bool v2Callbacks = false) {
        if (mSession == nullptr || mPreviewRequest == nullptr) {
            ALOGE("Testcase cannot start preview: session %p, preview request %p",
                    mSession, mPreviewRequest);
            return ACAMERA_ERROR_UNKNOWN;
        }
        int previewSeqId;
        camera_status_t ret;
        if (sequenceId == nullptr) {
            ret = ACameraCaptureSession_setRepeatingRequest(
                   mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
        } else if (physicalIdCnt == 0) {
            if (v2Callbacks) {
                ret = ACameraCaptureSession_setRepeatingRequestV2(
                      mSession, &mResultCb2, 1, &mPreviewRequest, sequenceId);
            } else {
                ret = ACameraCaptureSession_setRepeatingRequest(
                      mSession, &mResultCb, 1, &mPreviewRequest, sequenceId);
            }
        } else {
            if (extraPhysicalOutputs == nullptr) {
                ALOGE("Testcase missing valid physical camera Ids for logical camera");
                return ACAMERA_ERROR_INVALID_PARAMETER;
            }
            CaptureResultListener* resultListener =
                    static_cast<CaptureResultListener*>(mLogicalCameraResultCb.context);
            resultListener->registerPhysicalResults(physicalIdCnt, extraPhysicalOutputs);
            if (v2Callbacks) {
                ret = ACameraCaptureSession_logicalCamera_setRepeatingRequestV2(
                        mSession, &mLogicalCameraResultCb2, 1, &mPreviewRequest, sequenceId);
            } else {
                ret = ACameraCaptureSession_logicalCamera_setRepeatingRequest(
                        mSession, &mLogicalCameraResultCb, 1, &mPreviewRequest, sequenceId);
            }
        }
        return ret;
    }

    camera_status_t startRepeatingRequest(int *sequenceId, ACaptureRequest *request,
            ACameraCaptureSession_captureCallbacks *resultCb) {
        if (mSession == nullptr || request == nullptr || resultCb == nullptr) {
            ALOGE("Testcase cannot start repeating request: session %p, request %p resultCb %p",
                    mSession, request, resultCb);
            return ACAMERA_ERROR_UNKNOWN;
        }

        return ACameraCaptureSession_setRepeatingRequest(mSession, resultCb, 1, &request,
                sequenceId);
    }

    camera_status_t stopPreview() {
        if (mSession == nullptr) {
            ALOGE("Testcase cannot stop preview: session %p", mSession);
            return ACAMERA_ERROR_UNKNOWN;
        }
        return ACameraCaptureSession_stopRepeating(mSession);
    }

    camera_status_t abortCaptures() {
        if (mSession == nullptr) {
            ALOGE("Testcase cannot abort session %p", mSession);
            return ACAMERA_ERROR_UNKNOWN;
        }
        return ACameraCaptureSession_abortCaptures(mSession);
    }

    camera_status_t updateRepeatingRequest(ACaptureRequest *updatedRequest,
            int *sequenceId = nullptr) {
        if (mSession == nullptr || updatedRequest == nullptr) {
            ALOGE("Testcase cannot update repeating request: session %p, updated request %p",
                    mSession, updatedRequest);
            return ACAMERA_ERROR_UNKNOWN;
        }

        int previewSeqId;
        camera_status_t ret;
        if (sequenceId == nullptr) {
            ret = ACameraCaptureSession_setRepeatingRequest(
                    mSession, nullptr, 1, &updatedRequest, &previewSeqId);
        } else {
            ret = ACameraCaptureSession_setRepeatingRequest(
                    mSession, &mResultCb, 1, &updatedRequest, sequenceId);
        }
        return ret;
    }

    int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
        return mResultListener.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
    }

    bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
        return mResultListener.waitForFrameNumber(frameNumber, timeoutSec);
    }

    bool waitForFrameNumberStarted(int64_t frameNumber, uint32_t timeoutSec) {
        return mResultListener.waitForFrameNumberStarted(frameNumber, timeoutSec);
    }

    camera_status_t takePicture() {
        if (mSession == nullptr || mStillRequest == nullptr) {
            ALOGE("Testcase cannot take picture: session %p, still request %p",
                    mSession, mStillRequest);
            return ACAMERA_ERROR_UNKNOWN;
        }
        int seqId;
        return ACameraCaptureSession_capture(
                mSession, nullptr, 1, &mStillRequest, &seqId);
    }

    camera_status_t capture(ACaptureRequest* request,
            ACameraCaptureSession_captureCallbacks* listener,
            /*out*/int* seqId) {
        if (mSession == nullptr || request == nullptr) {
            ALOGE("Testcase cannot capture session: session %p, request %p",
                    mSession, request);
            return ACAMERA_ERROR_UNKNOWN;
        }
        return ACameraCaptureSession_capture(
                mSession, listener, 1, &request, seqId);
    }

    camera_status_t resetWithErrorLog() {
        camera_status_t ret;

        closeSession();

        for (int i = 0; i < 50; i++) {
            usleep(100000); // sleep 100ms
            if (mSessionListener.isClosed()) {
                ALOGI("Session take ~%d ms to close", i*100);
                break;
            }
        }

        if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
            LOG_ERROR(errorString,
                    "Session for camera %s close error. isClosde %d close count %d",
                    mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
            return ACAMERA_ERROR_UNKNOWN;
        }
        mSessionListener.reset();
        mResultListener.reset();

        ret = closeCamera();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
            return ret;
        }

        resetCamera();
        return ACAMERA_OK;
    }

    CaptureSessionListener* getSessionListener() {
        return &mSessionListener;
    }

    ACameraDevice* getCameraDevice() {
        return mDevice;
    }

    ACaptureSessionOutput *getPreviewOutput() {
        return mPreviewOutput;
    }

  private:
    ACameraManager* createManager() {
        if (!mCameraManager) {
            mCameraManager = ACameraManager_create();
        }
        return mCameraManager;
    }

    CameraServiceListener mServiceListener;
    ACameraManager_AvailabilityCallbacks mServiceCb {
        &mServiceListener,
        CameraServiceListener::onAvailable,
        CameraServiceListener::onUnavailable
    };
    CameraDeviceListener mDeviceListener;
    ACameraDevice_StateCallbacks mDeviceCb {
        &mDeviceListener,
        CameraDeviceListener::onDisconnected,
        CameraDeviceListener::onError
    };
    CaptureSessionListener mSessionListener;
    ACameraCaptureSession_stateCallbacks mSessionCb {
        &mSessionListener,
        CaptureSessionListener::onClosed,
        CaptureSessionListener::onReady,
        CaptureSessionListener::onActive
    };

    ACameraCaptureSession_prepareCallback mPreparedCb  = &CaptureSessionListener::onWindowPrepared;

    CaptureResultListener mResultListener;
    ACameraCaptureSession_captureCallbacks mResultCb {
        &mResultListener,
        CaptureResultListener::onCaptureStart,
        CaptureResultListener::onCaptureProgressed,
        CaptureResultListener::onCaptureCompleted,
        CaptureResultListener::onCaptureFailed,
        CaptureResultListener::onCaptureSequenceCompleted,
        CaptureResultListener::onCaptureSequenceAborted,
        CaptureResultListener::onCaptureBufferLost
    };

    ACameraCaptureSession_captureCallbacksV2 mResultCb2 {
        &mResultListener,
        CaptureResultListener::onCaptureStartV2,
        CaptureResultListener::onCaptureProgressed,
        CaptureResultListener::onCaptureCompleted,
        CaptureResultListener::onCaptureFailed,
        CaptureResultListener::onCaptureSequenceCompleted,
        CaptureResultListener::onCaptureSequenceAborted,
        CaptureResultListener::onCaptureBufferLost
    };

    ACameraCaptureSession_logicalCamera_captureCallbacksV2 mLogicalCameraResultCb2 {
        &mResultListener,
        CaptureResultListener::onCaptureStartV2,
        CaptureResultListener::onCaptureProgressed,
        CaptureResultListener::onLogicalCameraCaptureCompleted,
        CaptureResultListener::onLogicalCameraCaptureFailed,
        CaptureResultListener::onCaptureSequenceCompleted,
        CaptureResultListener::onCaptureSequenceAborted,
        CaptureResultListener::onCaptureBufferLost
    };

    ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCameraResultCb {
        &mResultListener,
        CaptureResultListener::onCaptureStart,
        CaptureResultListener::onCaptureProgressed,
        CaptureResultListener::onLogicalCameraCaptureCompleted,
        CaptureResultListener::onLogicalCameraCaptureFailed,
        CaptureResultListener::onCaptureSequenceCompleted,
        CaptureResultListener::onCaptureSequenceAborted,
        CaptureResultListener::onCaptureBufferLost
    };

    ACameraIdList* mCameraIdList = nullptr;
    ACameraDevice* mDevice = nullptr;
    AImageReader* mImgReader = nullptr;
    ANativeWindow* mImgReaderAnw = nullptr;
    ANativeWindow* mPreviewAnw = nullptr;
    ACameraManager* mCameraManager = nullptr;
    ACaptureSessionOutputContainer* mOutputs = nullptr;
    ACaptureSessionOutput* mPreviewOutput = nullptr;
    ACaptureSessionOutput* mImgReaderOutput = nullptr;
    ACameraCaptureSession* mSession = nullptr;
    ACaptureRequest* mPreviewRequest = nullptr;
    ACaptureRequest* mStillRequest = nullptr;
    ACameraOutputTarget* mReqPreviewOutput = nullptr;
    ACameraOutputTarget* mReqImgReaderOutput = nullptr;
    const char* mCameraId;
    JNIEnv* mJNIEnv = nullptr;
    jstring mJOverrideCameraId;
    const char* mOverrideCameraId = nullptr;

    bool mMgrInited = false; // cameraId, serviceListener
    bool mImgReaderInited = false;
    bool mPreviewInited = false;
};

jint throwAssertionError(JNIEnv* env, const char* message)
{
    jclass assertionClass;
    const char* className = "junit/framework/AssertionFailedError";

    assertionClass = env->FindClass(className);
    if (assertionClass == nullptr) {
        ALOGE("Native throw error: cannot find class %s", className);
        return -1;
    }
    return env->ThrowNew(assertionClass, message);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
testCameraManagerGetAndCloseNative(
        JNIEnv* env, jclass /*clazz*/) {
    bool pass = false;
    ALOGV("%s", __FUNCTION__);
    ACameraManager* cameraManager2 = nullptr;
    ACameraManager* cameraManager3 = nullptr;
    ACameraManager* cameraManager4 = nullptr;
    camera_status_t ret = ACAMERA_OK;
    ACameraManager* cameraManager = ACameraManager_create();
    if (cameraManager == nullptr) {
        LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
        goto cleanup;
    }
    ACameraManager_delete(cameraManager);
    cameraManager = nullptr;

    // Test get/close multiple instances
    cameraManager = ACameraManager_create();
    cameraManager2 = ACameraManager_create();
    if (cameraManager2 == nullptr) {
        LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
        goto cleanup;
    }
    ACameraManager_delete(cameraManager);
    cameraManager = nullptr;
    cameraManager3 = ACameraManager_create();
    if (cameraManager3 == nullptr) {
        LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
        goto cleanup;
    }
    cameraManager4 = ACameraManager_create();
        if (cameraManager4 == nullptr) {
        LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
        goto cleanup;
    }
    ACameraManager_delete(cameraManager3);
    ACameraManager_delete(cameraManager2);
    ACameraManager_delete(cameraManager4);

    pass = true;
cleanup:
    if (cameraManager) {
        ACameraManager_delete(cameraManager);
    }
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
testCameraManagerGetCameraIdsNative(
        JNIEnv* env, jclass /*clazz*/) {
    ALOGV("%s", __FUNCTION__);
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraIdList *cameraIdList = nullptr;
    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
    if (ret != ACAMERA_OK || cameraIdList == nullptr) {
        LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
                ret, cameraIdList);
        goto cleanup;
    }
    ALOGI("Number of cameras: %d", cameraIdList->numCameras);
    for (int i = 0; i < cameraIdList->numCameras; i++) {
        ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
    }
    ACameraManager_deleteCameraIdList(cameraIdList);
    cameraIdList = nullptr;

    pass = true;
cleanup:
    if (mgr) {
        ACameraManager_delete(mgr);
    }
    if (cameraIdList) {
        ACameraManager_deleteCameraIdList(cameraIdList);
    }
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
testCameraManagerExtendedAvailabilityCallbackNative(
        JNIEnv* env, jclass /*clazz*/) {
    ALOGV("%s", __FUNCTION__);
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraIdList *cameraIdList = nullptr;
    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
    int numCameras = cameraIdList->numCameras;
    CameraServiceListener listener;
    CameraServiceListener::StringPairSet unavailablePhysicalCameras;
    CameraServiceListener::StringPairSet physicalCameraIdPairs;
    ACameraManager_ExtendedAvailabilityCallbacks cbs {
            {
                &listener,
                CameraServiceListener::onAvailable,
                CameraServiceListener::onUnavailable
            },
            CameraServiceListener::onCameraAccessPrioritiesChanged,
            CameraServiceListener::onPhysicalCameraAvailable,
            CameraServiceListener::onPhysicalCameraUnavailable,
            {}
    };

    ret = ACameraManager_registerExtendedAvailabilityCallback(mgr, &cbs);
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Register extended availability callback failed: ret %d", ret);
        goto cleanup;
    }
    sleep(1); // sleep a second to give some time for callbacks to happen

    // Should at least get onAvailable for each camera once
    if (listener.getAvailableCount() < numCameras) {
        LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
                numCameras, listener.getAvailableCount());
        goto cleanup;
    }

    {
        int availablePhysicalCamera = listener.getPhysicalCameraAvailableCount();
        if (availablePhysicalCamera > 0) {
            LOG_ERROR(errorString, "Expect no available callback, but got %d",
                    availablePhysicalCamera);
        }
    }

    unavailablePhysicalCameras = listener.getUnavailablePhysicalCameras();
    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = cameraIdList->cameraIds[i];
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }
        ACameraMetadata* c;
        ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &c);
        if (ret != ACAMERA_OK || c == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
            goto cleanup;
        }
        std::unique_ptr<ACameraMetadata> chars(c);

        size_t physicalCameraCnt = 0;
        const char *const* physicalCameraIds = nullptr;
        if (!ACameraMetadata_isLogicalMultiCamera(
                chars.get(), &physicalCameraCnt, &physicalCameraIds)) {
            continue;
        }
        for (size_t j = 0; j < physicalCameraCnt; j++) {
            physicalCameraIdPairs.emplace(cameraId, physicalCameraIds[j]);
        }
    }
    for (const auto& unavailIdPair : unavailablePhysicalCameras) {
        bool validPair = false;
        for (const auto& idPair : physicalCameraIdPairs) {
            if (idPair.first == unavailIdPair.first && idPair.second == unavailIdPair.second) {
                validPair = true;
                break;
            }
        }
        if (!validPair) {
            LOG_ERROR(errorString, "Expect valid unavailable physical cameras, but got %s : %s",
                    unavailIdPair.first.c_str(), unavailIdPair.second.c_str());
            goto cleanup;
        }
    }

    ret = ACameraManager_unregisterExtendedAvailabilityCallback(mgr, &cbs);
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Unregister extended availability callback failed: ret %d", ret);
        goto cleanup;
    }
    pass = true;
cleanup:
    if (cameraIdList) {
        ACameraManager_deleteCameraIdList(cameraIdList);
    }
    if (mgr) {
        ACameraManager_delete(mgr);
    }
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
testCameraManagerAvailabilityCallbackNative(
        JNIEnv* env, jclass /*clazz*/) {
    ALOGV("%s", __FUNCTION__);
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraIdList *cameraIdList = nullptr;
    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
    int numCameras = cameraIdList->numCameras;
    CameraServiceListener listener;
    ACameraManager_AvailabilityCallbacks cbs {
            &listener,
            CameraServiceListener::onAvailable,
            CameraServiceListener::onUnavailable};
    ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
        goto cleanup;
    }
    sleep(1); // sleep a second to give some time for callbacks to happen

    // Should at least get onAvailable for each camera once
    if (listener.getAvailableCount() < numCameras) {
        LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
                numCameras, listener.getAvailableCount());
        goto cleanup;
    }

    ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
        goto cleanup;
    }
    pass = true;
cleanup:
    if (cameraIdList) {
        ACameraManager_deleteCameraIdList(cameraIdList);
    }
    if (mgr) {
        ACameraManager_delete(mgr);
    }
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
testCameraManagerCharacteristicsNative(
        JNIEnv* env, jclass /*clazz*/) {
    ALOGV("%s", __FUNCTION__);
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraIdList *cameraIdList = nullptr;
    ACameraMetadata* chars = nullptr;
    ACameraMetadata* copy = nullptr;
    int numCameras = 0;
    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
    if (ret != ACAMERA_OK || cameraIdList == nullptr) {
        LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
                ret, cameraIdList);
        goto cleanup;
    }
    numCameras = cameraIdList->numCameras;

    for (int i = 0; i < numCameras; i++) {
        ret = ACameraManager_getCameraCharacteristics(
                mgr, cameraIdList->cameraIds[i], &chars);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
            goto cleanup;
        }

        int32_t numTags = 0;
        const uint32_t* tags = nullptr;
        ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
            goto cleanup;
        }

        for (int tid = 0; tid < numTags; tid++) {
            uint32_t tagId = tags[tid];
            ALOGV("%s camera characteristics contains key %u", __FUNCTION__, tagId);
            uint32_t sectionId = tagId >> 16;
            if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
                LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
                goto cleanup;
            }
        }

        ACameraMetadata_const_entry entry;
        ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
            goto cleanup;
        }

        // Check the entry is actually legit
        if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
                entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
            LOG_ERROR(errorString,
                    "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
                    "type %d (expected %d), data %p (expected not null)",
                    entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
                    entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
            goto cleanup;
        }
        // All camera supports BC except depth only cameras
        bool supportBC = false, supportDepth = false;
        for (uint32_t i = 0; i < entry.count; i++) {
            if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
                supportBC = true;
            }
            if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
                supportDepth = true;
            }
        }
        if (!(supportBC || supportDepth)) {
            LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
                    cameraIdList->cameraIds[i]);
            goto cleanup;
        }

        // Check copy works
        copy = ACameraMetadata_copy(chars);

        // Compare copy with original
        ACameraMetadata_const_entry entryCopy;
        ret = ACameraMetadata_getConstEntry(
                copy, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entryCopy);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
            goto cleanup;
        }
        for (uint32_t i = 0; i < entry.count; i++) {
            if (entry.data.u8[i] != entryCopy.data.u8[i]) {
                LOG_ERROR(errorString,
                    "Copy of available capability key[%d]: %d mismatches original %d",
                    i, entryCopy.data.u8[i], entry.data.u8[i]);
                goto cleanup;
            }
        }

        // Check get unknown value fails
        uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
        ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
        if (ret == ACAMERA_OK) {
            LOG_ERROR(errorString, "Error: get unknown tag should fail!");
            goto cleanup;
        }

        ACameraMetadata_free(chars);
        ACameraMetadata_free(copy);
        chars = nullptr;
        copy = nullptr;
    }

    pass = true;
cleanup:
    if (chars) {
        ACameraMetadata_free(chars);
    }
    if (copy) {
        ACameraMetadata_free(copy);
    }
    ACameraManager_deleteCameraIdList(cameraIdList);
    ACameraManager_delete(mgr);
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceOpenAndCloseNative(
        JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    PreviewTestCase testCase;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        ret = testCase.closeCamera();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceCreateCaptureRequestNative(
        JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraIdList* cameraIdList = nullptr;
    ACameraDevice* device = nullptr;
    ACaptureRequest* request = nullptr;
    ACameraMetadata* chars = nullptr;
    camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);

    int numCameras = cameraIdList->numCameras;
    const char* overrideCameraId = nullptr;
    if (jOverrideCameraId != nullptr) {
        overrideCameraId = env->GetStringUTFChars(jOverrideCameraId, nullptr);
    }

    for (int i = 0; i < numCameras; i++) {
        CameraDeviceListener deviceListener;
        const char* cameraId = cameraIdList->cameraIds[i];
        if (overrideCameraId != nullptr && strcmp(overrideCameraId, cameraId)) {
            // Skip other cameras if overriding camera id to be tested.
            continue;
        }
        ACameraDevice_StateCallbacks deviceCb {
            &deviceListener,
            CameraDeviceListener::onDisconnected,
            CameraDeviceListener::onError
        };
        ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
        if (ret != ACAMERA_OK || chars == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
                    cameraId, ret, chars);
            goto cleanup;
        }
        StaticInfo staticInfo(chars);

        for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
            ACameraDevice_request_template templateId =
                    static_cast<ACameraDevice_request_template>(t);
            ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
            if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
                // template not supported. skip
                continue;
            }

            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
                goto cleanup;
            }

            int32_t numTags = 0;
            const uint32_t* tags = nullptr;
            ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
                goto cleanup;
            }

            for (int tid = 0; tid < numTags; tid++) {
                uint32_t tagId = tags[tid];
                ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
                uint32_t sectionId = tagId >> 16;
                if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
                    LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
                    goto cleanup;
                }
            }

            void* context = nullptr;
            ret = ACaptureRequest_getUserContext(request, &context);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
                goto cleanup;
            }
            if (context != nullptr) {
                LOG_ERROR(errorString, "Capture request context is not null: %p", context);
                goto cleanup;
            }

            intptr_t magic_num = 0xBEEF;
            ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
                goto cleanup;
            }

            ret = ACaptureRequest_getUserContext(request, &context);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
                goto cleanup;
            }
            if (context != (void*) magic_num) {
                LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
                goto cleanup;
            }

            // try get/set capture request fields
            ACameraMetadata_const_entry entry;
            ret = ACaptureRequest_getConstEntry_physicalCamera(request, nullptr,
                    ACAMERA_CONTROL_AE_MODE, &entry);
            if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
                LOG_ERROR(errorString, "Get AE mode key for null physical id should fail. ret %d",
                        ret);
                goto cleanup;
            }
            ret = ACaptureRequest_getConstEntry_physicalCamera(request, cameraId,
                    ACAMERA_CONTROL_AE_MODE, &entry);
            if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
                LOG_ERROR(errorString, "Get AE mode key for physical id should fail. ret %d",
                        ret);
                goto cleanup;
            }
            ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
                goto cleanup;
            }

            if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
                    entry.count != 1) {
                LOG_ERROR(errorString,
                        "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
                        "count %d (expect %d)",
                        entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
                        entry.count, 1);
                goto cleanup;
            }
            if (t == TEMPLATE_MANUAL) {
                if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
                    LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
                            entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
                    goto cleanup;
                }
                // try set AE_MODE_ON
                uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
                ret = ACaptureRequest_setEntry_physicalCamera_u8(
                        request, nullptr, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
                if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
                    LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
                            "fail. ret %d", cameraId, ret);
                    goto cleanup;
                }
                ret = ACaptureRequest_setEntry_physicalCamera_u8(
                        request, cameraId, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
                if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
                    LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
                            "fail. ret %d", cameraId, ret);
                    goto cleanup;
                }
                ret = ACaptureRequest_setEntry_u8(
                        request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
                if (ret != ACAMERA_OK) {
                    LOG_ERROR(errorString,
                            "Error: Camera %s template %d: update AE mode key fail. ret %d",
                            cameraId, t, ret);
                    goto cleanup;
                }
                ret = ACaptureRequest_getConstEntry(
                        request, ACAMERA_CONTROL_AE_MODE, &entry);
                if (ret != ACAMERA_OK) {
                    LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
                    goto cleanup;
                }
                if (entry.data.u8[0] != aeMode) {
                    LOG_ERROR(errorString,
                            "Error: AE mode key is not updated. expect %d but get %d",
                            aeMode, entry.data.u8[0]);
                    goto cleanup;
                }
            } else {
                if (staticInfo.isColorOutputSupported()) {
                    if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
                        LOG_ERROR(errorString,
                                "Error: Template %d has wrong AE mode %d (expect %d)",
                                t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
                        goto cleanup;
                    }
                    // try set AE_MODE_OFF
                    if (staticInfo.isCapabilitySupported(
                            ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
                        uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
                        ret = ACaptureRequest_setEntry_u8(
                                request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
                        if (ret != ACAMERA_OK) {
                            LOG_ERROR(errorString,
                                    "Error: Camera %s template %d: update AE mode key fail. ret %d",
                                    cameraId, t, ret);
                            goto cleanup;
                        }
                        ret = ACaptureRequest_getConstEntry(
                                request, ACAMERA_CONTROL_AE_MODE, &entry);
                        if (ret != ACAMERA_OK) {
                            LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
                            goto cleanup;
                        }
                        if (entry.data.u8[0] != aeMode) {
                            LOG_ERROR(errorString,
                                    "Error: AE mode key is not updated. expect %d but get %d",
                                    aeMode, entry.data.u8[0]);
                            goto cleanup;
                        }
                    }
                }
            }
            ACaptureRequest_free(request);
            request = nullptr;
        }

        ACameraMetadata_free(chars);
        chars = nullptr;
        ACameraDevice_close(device);
        device = nullptr;
    }

    pass = true;
cleanup:
    if (cameraIdList) {
        ACameraManager_deleteCameraIdList(cameraIdList);
    }
    if (request) {
        ACaptureRequest_free(request);
    }
    if (chars) {
        ACameraMetadata_free(chars);
    }
    if (device) {
        ACameraDevice_close(device);
    }
    if (mgr) {
        ACameraManager_delete(mgr);
    }
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSessionOpenAndCloseNative(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    PreviewTestCase testCase;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        {
            ACameraMetadata* chars = testCase.getCameraChars(cameraId);
            StaticInfo staticInfo(chars);
            if (!staticInfo.isColorOutputSupported()) {
                ALOGI("%s: camera %s does not support color output. skipping",
                        __FUNCTION__, cameraId);
                ACameraMetadata_free(chars);
                continue;
            }
            ACameraMetadata_free(chars);
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }

        CaptureSessionListener* sessionListener = testCase.getSessionListener();
        if (sessionListener == nullptr) {
            LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
            goto cleanup;
        }

        // Try open/close session multiple times
        for (int j = 0; j < 5; j++) {
            ret = testCase.createCaptureSessionWithLog();
            if (ret != ACAMERA_OK) {
                // Don't log error here. testcase did it
                goto cleanup;
            }

            usleep(100000); // sleep to give some time for callbacks to happen

            if (!sessionListener->isIdle()) {
                LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
                        cameraId);
                goto cleanup;
            }

            testCase.closeSession();

            usleep(100000); // sleep to give some time for callbacks to happen
            if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
                LOG_ERROR(errorString,
                        "Session for camera %s close error. isClosde %d close count %d",
                        cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
                goto cleanup;
            }
            sessionListener->reset();
        }

        // Try open/close really fast
        ret = testCase.createCaptureSessionWithLog();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }
        testCase.closeSession();
        usleep(100000); // sleep to give some time for callbacks to happen
        if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
            LOG_ERROR(errorString,
                    "Session for camera %s close error. isClosde %d close count %d",
                    cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
            goto cleanup;
        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSharedOutputUpdate(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    PreviewTestCase testCase;
    int sequenceId = -1;
    int64_t lastFrameNumber = 0;
    bool frameArrived = false;
    ANativeWindow* previewAnw = nullptr;
    ANativeWindow* sharedAnw = ANativeWindow_fromSurface(env, jSharedSurface);
    ACaptureRequest* updatedRequest = nullptr;
    ACameraOutputTarget* reqPreviewOutput = nullptr;
    ACameraOutputTarget* reqSharedOutput = nullptr;
    ACaptureSessionOutput *previewOutput = nullptr;
    uint32_t timeoutSec = 1;
    uint32_t runPreviewSec = 2;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        {
            ACameraMetadata* chars = testCase.getCameraChars(cameraId);
            StaticInfo staticInfo(chars);
            if (!staticInfo.isColorOutputSupported()) {
                ALOGI("%s: camera %s does not support color output. skipping",
                        __FUNCTION__, cameraId);
                ACameraMetadata_free(chars);
                continue;
            }
            ACameraMetadata_free(chars);
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }

        ret = testCase.createCaptureSessionWithLog(true);
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.createRequestsWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.startPreview();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Start preview failed!");
            goto cleanup;
        }

        sleep(runPreviewSec);

        previewOutput = testCase.getPreviewOutput();
        //Try some bad input
        ret = ACaptureSessionSharedOutput_add(previewOutput, previewAnw);
        if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
            LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add should return invalid "
                    "parameter! %d", ret);
            goto cleanup;
        }

        ret = ACaptureSessionSharedOutput_remove(previewOutput, previewAnw);
        if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
            LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove should return invalid "
                    "parameter! %d", ret);
            goto cleanup;
        }

        //Now try with valid input
        ret = ACaptureSessionSharedOutput_add(previewOutput, sharedAnw);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add failed!")
            goto cleanup;
        }

        ret = testCase.updateOutput(env, previewOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Failed to update output configuration!")
            goto cleanup;
        }

        ret = ACameraDevice_createCaptureRequest(
                testCase.getCameraDevice(), TEMPLATE_PREVIEW, &updatedRequest);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        ret = ACameraOutputTarget_create(previewAnw, &reqPreviewOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString,
                    "Camera %s create request preview output target failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        ret = ACaptureRequest_addTarget(updatedRequest, reqPreviewOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        ret = ACameraOutputTarget_create(sharedAnw, &reqSharedOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString,
                    "Camera %s create request preview output target failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        ret = ACaptureRequest_addTarget(updatedRequest, reqSharedOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        ret = testCase.updateRepeatingRequest(updatedRequest, &sequenceId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        sleep(runPreviewSec);

        ret = ACaptureSessionSharedOutput_remove(previewOutput, sharedAnw);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove failed!");
            goto cleanup;
        }

        //Try removing shared output which still has pending camera requests
        ret = testCase.updateOutput(env, previewOutput);
        if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
            LOG_ERROR(errorString, "updateOutput should fail!");
            goto cleanup;
        }

        //Remove the shared output correctly by updating the repeating request
        //first
        ret = ACaptureRequest_removeTarget(updatedRequest, reqSharedOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Camera %s remove target output failed. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        ret = testCase.updateRepeatingRequest(updatedRequest);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
                    cameraId, ret);
            goto cleanup;
        }

        //Then wait for all old requests to flush
        lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
        if (lastFrameNumber < 0) {
            LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
                    cameraId);
            goto cleanup;
        }

        frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
        if (!frameArrived) {
            LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
                    cameraId);
            goto cleanup;
        }

        ret = testCase.updateOutput(env, previewOutput);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "updateOutput failed!");
            goto cleanup;
        }

        sleep(runPreviewSec);

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;

cleanup:

    if (updatedRequest != nullptr) {
        ACaptureRequest_free(updatedRequest);
        updatedRequest = nullptr;
    }

    if (reqPreviewOutput != nullptr) {
        ACameraOutputTarget_free(reqPreviewOutput);
        reqPreviewOutput = nullptr;
    }

    if (reqSharedOutput != nullptr) {
        ACameraOutputTarget_free(reqSharedOutput);
        reqSharedOutput = nullptr;
    }

    if (sharedAnw) {
        ANativeWindow_release(sharedAnw);
        sharedAnw = nullptr;
    }

    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

bool testCameraDeviceSimplePreviewNativeInternal(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId, bool v2Callbacks) {
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    const int timeoutSec = 1;
    PreviewTestCase testCase;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        {
            ACameraMetadata* chars = testCase.getCameraChars(cameraId);
            StaticInfo staticInfo(chars);
            if (!staticInfo.isColorOutputSupported()) {
                ALOGI("%s: camera %s does not support color output. skipping",
                        __FUNCTION__, cameraId);
                ACameraMetadata_free(chars);
                continue;
            }
            ACameraMetadata_free(chars);
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }

        ret = testCase.createCaptureSessionWithLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.createRequestsWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }
        int sequenceId = 0;
        ret = testCase.startPreview(&sequenceId, 0, nullptr, v2Callbacks);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Start preview failed!");
            goto cleanup;
        }

        sleep(3);

        ret = testCase.stopPreview();
        if (ret != ACAMERA_OK) {
            ALOGE("%s: stopPreview failed", __FUNCTION__);
            LOG_ERROR(errorString, "stopPreview failed!");
            goto cleanup;
        }

        //Then wait for all old requests to flush
        int64_t lastFrameNumber =
                testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
        if (lastFrameNumber < 0) {
            LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
                    cameraId);
            goto cleanup;
        }
        if (v2Callbacks) {
              bool frameStarted = testCase.waitForFrameNumberStarted(lastFrameNumber, timeoutSec);
            if (!frameStarted) {
                LOG_ERROR(errorString, "Camera %s timed out waiting on onCaptureStart for last"
                        "frame number!", cameraId);
                goto cleanup;
            }

        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSimplePreviewNative(
        JNIEnv* env, jclass clazz, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return testCameraDeviceSimplePreviewNativeInternal(env, clazz, jPreviewSurface,
            jOverrideCameraId, /*v2Callbacks*/false);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceSimplePreviewNative2(
        JNIEnv* env, jclass clazz, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return testCameraDeviceSimplePreviewNativeInternal(env, clazz, jPreviewSurface,
            jOverrideCameraId, /*v2Callbacks*/true);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDevicePreviewWithSessionParametersNative(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraMetadata* chars = nullptr;
    PreviewTestCase testCase;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        ret = ACameraManager_getCameraCharacteristics(
                mgr, cameraId, &chars);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
            goto cleanup;
        }

        StaticInfo staticInfo(chars);
        ACameraMetadata_const_entry sessionParamKeys{};
        ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS,
                &sessionParamKeys);
        if ((ret != ACAMERA_OK) || (sessionParamKeys.count == 0) ||
                !staticInfo.isColorOutputSupported()) {
            ACameraMetadata_free(chars);
            chars = nullptr;
            continue;
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }

        ret = testCase.createRequestsWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ACaptureRequest *previewRequest = nullptr;
        ret = testCase.getPreviewRequest(&previewRequest);
        if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
            LOG_ERROR(errorString, "Preview request query failed!");
            goto cleanup;
        }

        ret = testCase.createCaptureSessionWithLog(/*isPreviewShared*/ false, previewRequest);
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.startPreview();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Start preview failed!");
            goto cleanup;
        }

        sleep(3);

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }

        ACameraMetadata_free(chars);
        chars = nullptr;
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    if (chars) {
        ACameraMetadata_free(chars);
    }
    ACameraManager_delete(mgr);
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

bool nativeCameraDeviceTestPrepareSurface(
        JNIEnv* env, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    const int NUM_TEST_IMAGES = 10;
    const int TEST_WIDTH  = 640;
    const int TEST_HEIGHT = 480;
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraMetadata* chars = nullptr;
    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
    PreviewTestCase testCase;
    int64_t lastFrameNumber = 0;
    bool frameStarted = false;
    bool frameArrived = false;
    uint32_t timeoutSec = 1;
    uint32_t runPreviewSec = 2;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        chars = testCase.getCameraChars(cameraId);
        if (chars == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
            goto cleanup;
        }
        StaticInfo staticInfo(chars);
        if (!staticInfo.isColorOutputSupported()) {
            ALOGI("%s: camera %s does not support color output. skipping",
                    __FUNCTION__, cameraId);
            ACameraMetadata_free(chars);
            chars = nullptr;
            continue;
        }
        ACameraMetadata_free(chars);
        chars = nullptr;

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(1000000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }
        ImageReaderListener readerListener;
        AImageReader* reader = nullptr;
        ANativeWindow* readerAnw = nullptr;
        ACaptureSessionOutput* readerSessionOutput = nullptr;
        ACameraOutputTarget* readerOutput = nullptr;
        AImageReader_ImageListener readerCb {
            &readerListener,
            ImageReaderListener::validateImageCb
        };

        mediaRet = testCase.initImageReaderWithErrorLog(
                TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
                &readerCb, &reader, &readerAnw);
        if (mediaRet != AMEDIA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = ACaptureSessionOutput_create(readerAnw,
                &readerSessionOutput);
        if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }
        std::vector<ACaptureSessionOutput *> readerSessionOutputs = {readerSessionOutput};
        ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
                nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
        if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
                ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
            // Camera device doesn't support the stream combination, skip the
            // current camera.
            testCase.closeCamera();
            testCase.resetCamera();
            continue;
        } else if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }
        // Set the callback on the created capture session and prepare all the surfaces
        if (testCase.setWindowPreparedCallback() != ACAMERA_OK ||
                testCase.prepareWindow(previewAnw) != ACAMERA_OK) {
            goto cleanup;
        }
        if (testCase.prepareWindow(readerAnw) != ACAMERA_OK) {
            goto cleanup;
        }
        // Wait for some time - we should've gotten onWindowPrepared callbacks for all the
        // ANativeWindows.
        usleep(200000);
        if (!testCase.gotAllPreparedCallbacksWithErrorLog()) {
            goto cleanup;
        }
        std::vector<ACameraOutputTarget* > readerOutputs = {readerOutput};
        ret = testCase.createRequestsWithErrorLog(readerOutputs);
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ACaptureRequest *previewRequest = nullptr;
        ret = testCase.getPreviewRequest(&previewRequest);
        if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
            LOG_ERROR(errorString, "Preview request query failed!");
            goto cleanup;
        }

        int sequenceId = 0;
        ret = testCase.startPreview(&sequenceId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Start preview failed!");
            goto cleanup;
        }

        sleep(runPreviewSec);

        ret = testCase.stopPreview();
        if (ret != ACAMERA_OK) {
            ALOGE("%s: stopPreview failed", __FUNCTION__);
            LOG_ERROR(errorString, "stopPreview failed!");
            goto cleanup;
        }

        //Then wait for all old requests to flush
        lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
        if (lastFrameNumber < 0) {
            LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
                    cameraId);
            goto cleanup;
        }
        frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
        if (!frameArrived) {
            LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
                    cameraId);
            goto cleanup;
        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    if (chars) {
        ACameraMetadata_free(chars);
    }
    ACameraManager_delete(mgr);
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDevicePrepareSurface(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return nativeCameraDeviceTestPrepareSurface(env,
            jPreviewSurface, jOverrideCameraId);
}

bool nativeCameraDeviceLogicalPhysicalStreaming(
        JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings,
        jstring jOverrideCameraId, bool v2Callbacks) {
    const int NUM_TEST_IMAGES = 10;
    const int TEST_WIDTH  = 640;
    const int TEST_HEIGHT = 480;
    ALOGV("%s", __FUNCTION__);
    int numCameras = 0;
    bool pass = false;
    ACameraManager* mgr = ACameraManager_create();
    ACameraMetadata* chars = nullptr;
    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
    PreviewTestCase testCase;
    int64_t lastFrameNumber = 0;
    bool frameStarted = false;
    bool frameArrived = false;
    uint32_t timeoutSec = 1;
    uint32_t runPreviewSec = 2;

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        if (chars != nullptr) {
            ACameraMetadata_free(chars);
            chars = nullptr;
        }
        chars = testCase.getCameraChars(i);
        if (chars == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
            goto cleanup;
        }

        size_t physicalCameraCnt = 0;
        const char *const* physicalCameraIds = nullptr;
        if (!ACameraMetadata_isLogicalMultiCamera(
                chars, &physicalCameraCnt, &physicalCameraIds)) {
            continue;
        }
        if (physicalCameraCnt < 2) {
            LOG_ERROR(errorString, "Logical camera device %s only has %zu physical cameras",
                   cameraId, physicalCameraCnt);
            goto cleanup;
        }

        std::vector<const char*> candidateIds;
        for (size_t i = 0; i < physicalCameraCnt && candidateIds.size() < 2; i++) {
            ACameraMetadata* physicalChars = testCase.getCameraChars(physicalCameraIds[i]);
            if (physicalChars == nullptr) {
                LOG_ERROR(errorString,
                        "Get camera %s characteristics failure", physicalCameraIds[i]);
                goto cleanup;
            }
            StaticInfo info(physicalChars);
            bool testSizeSupported = info.isSizeSupportedForFormat(AIMAGE_FORMAT_YUV_420_888,
                    TEST_WIDTH, TEST_HEIGHT);
            ACameraMetadata_free(physicalChars);
            if (!testSizeSupported) {
                continue;
            }
            candidateIds.push_back(physicalCameraIds[i]);
        }
        if (candidateIds.size() < 2) {
            continue;
        }

        // Check physical camera request keys
        if (usePhysicalSettings) {
            ACameraMetadata_const_entry entry;
            camera_status_t status = ACameraMetadata_getConstEntry(
                    chars, ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &entry);
            if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
                // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
                ALOGI("%s camera id %s physical request keys not reported, skipping",
                        __FUNCTION__, cameraId);
                continue;
            } else if (status != ACAMERA_OK) {
                // Do not log error here. testcase did it.
                goto cleanup;
            } else if (entry.count == 0) {
                // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
                continue;
            }
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        std::vector<ImageReaderListener> readerListeners(2);
        std::vector<AImageReader_ImageListener> readerCbs;
        std::vector<AImageReader*> readers;
        std::vector<ANativeWindow*> readerAnws;
        std::vector<ACaptureSessionOutput*> readerSessionOutputs;
        std::vector<ACameraOutputTarget*> readerOutputs;
        for (size_t i = 0; i < 2; i++) {
            AImageReader_ImageListener readerCb {
                &readerListeners[i],
                ImageReaderListener::validateImageCb
            };
            readerCbs.push_back(readerCb);

            AImageReader* reader = nullptr;
            ANativeWindow* readerAnw = nullptr;
            ACaptureSessionOutput* readerSessionOutput = nullptr;
            ACameraOutputTarget* readerOutput = nullptr;
            mediaRet = testCase.initImageReaderWithErrorLog(
                    TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
                    &readerCb, &reader, &readerAnw);
            if (mediaRet != AMEDIA_OK) {
                // Don't log error here. testcase did it
                goto cleanup;
            }

            camera_status_t ret = ACaptureSessionPhysicalOutput_create(readerAnw,
                    candidateIds[i], &readerSessionOutput);
            if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
                if (ret == ACAMERA_OK) {
                    ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
                }
                // Don't log error here. testcase did it
                goto cleanup;
            }

            ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
            if (ret != ACAMERA_OK) {
                // Don't log error here. testcase did it
                goto cleanup;
            }

            readers.push_back(reader);
            readerAnws.push_back(readerAnw);
            readerSessionOutputs.push_back(readerSessionOutput);
            readerOutputs.push_back(readerOutput);
        }

        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }

        ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
                nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
        if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
                ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
            // Camera device doesn't support the stream combination, skip the
            // current camera.
            testCase.closeCamera();
            testCase.resetCamera();
            continue;
        } else if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        if (usePhysicalSettings) {
            std::vector<const char*> twoNullStr = {nullptr, nullptr};
            ACameraIdList nullCameraIdList = {2, twoNullStr.data()};
            ret = testCase.createRequestsWithErrorLog(readerOutputs, &nullCameraIdList);
            if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
                LOG_ERROR(errorString, "Null physical camera ids must fail createCaptureRequest. "
                        "ret %d", ret);
                goto cleanup;
            }

            std::string invalidId = "";
            std::vector<const char*> one0LengthStr = {invalidId.c_str()};
            ACameraIdList invalidCameraIdList = {1, one0LengthStr.data()};
            ret = testCase.createRequestsWithErrorLog(readerOutputs, &invalidCameraIdList);
            if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
                LOG_ERROR(errorString, "zero-length physical camera ids must fail "
                        "createCaptureRequest. ret %d", ret);
                goto cleanup;
            }

            ACameraIdList physicalCameraIdList = {2, candidateIds.data()};
            ret = testCase.createRequestsWithErrorLog(readerOutputs, &physicalCameraIdList);
        } else {
            ret = testCase.createRequestsWithErrorLog(readerOutputs);
        }
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ACaptureRequest *previewRequest = nullptr;
        ret = testCase.getPreviewRequest(&previewRequest);
        if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
            LOG_ERROR(errorString, "Preview request query failed!");
            goto cleanup;
        }

        int sequenceId = 0;
        ret = testCase.startPreview(&sequenceId, 2, candidateIds.data(), v2Callbacks);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Start preview failed!");
            goto cleanup;
        }

        sleep(runPreviewSec);

        ret = testCase.stopPreview();
        if (ret != ACAMERA_OK) {
            ALOGE("%s: stopPreview failed", __FUNCTION__);
            LOG_ERROR(errorString, "stopPreview failed!");
            goto cleanup;
        }

        //Then wait for all old requests to flush
        lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
        if (lastFrameNumber < 0) {
            LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
                    cameraId);
            goto cleanup;
        }
        if (v2Callbacks) {
              frameStarted = testCase.waitForFrameNumberStarted(lastFrameNumber, timeoutSec);
            if (!frameStarted) {
                LOG_ERROR(errorString, "Camera %s timed out waiting on onCaptureStart for last"
                        "frame number!", cameraId);
                goto cleanup;
            }

        }

        frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
        if (!frameArrived) {
            LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
                    cameraId);
            goto cleanup;
        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    if (chars) {
        ACameraMetadata_free(chars);
    }
    ACameraManager_delete(mgr);
    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceLogicalPhysicalStreamingNative(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return nativeCameraDeviceLogicalPhysicalStreaming(env,
            jPreviewSurface, false /*usePhysicalSettings*/,
            jOverrideCameraId, /*v2Callbacks*/false);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceLogicalPhysicalStreamingNative2(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return nativeCameraDeviceLogicalPhysicalStreaming(env,
            jPreviewSurface, false /*usePhysicalSettings*/,
            jOverrideCameraId, /*v2Callbacks*/true);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceLogicalPhysicalSettingsNative(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return nativeCameraDeviceLogicalPhysicalStreaming(env,
            jPreviewSurface, true /*usePhysicalSettings*/,
            jOverrideCameraId, /*v2Callbacks*/false);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceLogicalPhysicalSettingsNative2(
        JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    return nativeCameraDeviceLogicalPhysicalStreaming(env,
            jPreviewSurface, true /*usePhysicalSettings*/,
            jOverrideCameraId, /*v2Callbacks*/ true);
}

bool nativeImageReaderTestBase(
        JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb,
        jstring jOverrideCameraId) {
    const int NUM_TEST_IMAGES = 10;
    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
    int numCameras = 0;
    bool pass = false;
    PreviewTestCase testCase;
    ACameraMetadata* chars = nullptr;

    const char* outPath = (jOutPath == nullptr) ? nullptr :
            env->GetStringUTFChars(jOutPath, nullptr);
    if (outPath != nullptr) {
        ALOGI("%s: out path is %s", __FUNCTION__, outPath);
    }

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        {
            ACameraMetadata* chars = testCase.getCameraChars(cameraId);
            StaticInfo staticInfo(chars);
            if (!staticInfo.isColorOutputSupported()) {
                ALOGI("%s: camera %s does not support color output. skipping",
                        __FUNCTION__, cameraId);
                ACameraMetadata_free(chars);
                continue;
            }
            ACameraMetadata_free(chars);
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        chars = testCase.getCameraChars(i);
        if (chars == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
            goto cleanup;
        }
        StaticInfo staticInfo(chars);

        usleep(200000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        ImageReaderListener readerListener;
        AImageReader_ImageListener readerCb { &readerListener, cb };
        readerListener.setDumpFilePathBase(outPath);

        int32_t testWidth, testHeight;
        switch (format) {
            case AIMAGE_FORMAT_JPEG:
            case AIMAGE_FORMAT_Y8:
            case AIMAGE_FORMAT_HEIC:
            case AIMAGE_FORMAT_DEPTH_JPEG:
                if (!staticInfo.getMaxSizeForFormat(format, &testWidth, &testHeight)) {
                    // No corresponding format support, skip this device.
                    ACameraMetadata_free(chars);
                    chars = nullptr;
                    ret = testCase.closeCamera();
                    if (ret != ACAMERA_OK) {
                        LOG_ERROR(errorString, "Camera %s failed to close. ret %d ", cameraId, ret);
                        goto cleanup;
                    }

                    continue;
                }
                break;
            default:
                LOG_ERROR(errorString, "Testcase doesn't yet support format %d", format);
                goto cleanup;
        }
        mediaRet = testCase.initImageReaderWithErrorLog(
                testWidth, testHeight, format, NUM_TEST_IMAGES,
                &readerCb);
        if (mediaRet != AMEDIA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.createCaptureSessionWithLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.createRequestsWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        CaptureResultListener resultListener;
        ACameraCaptureSession_captureCallbacks resultCb {
            &resultListener,
            CaptureResultListener::onCaptureStart,
            CaptureResultListener::onCaptureProgressed,
            CaptureResultListener::onCaptureCompleted,
            CaptureResultListener::onCaptureFailed,
            CaptureResultListener::onCaptureSequenceCompleted,
            CaptureResultListener::onCaptureSequenceAborted,
            CaptureResultListener::onCaptureBufferLost
        };
        resultListener.setRequestSave(true);
        ACaptureRequest* requestTemplate = nullptr;
        ret = testCase.getStillRequest(&requestTemplate);
        if (ret != ACAMERA_OK || requestTemplate == nullptr) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        // Do some still capture
        int lastSeqId = -1;
        for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
            ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
            ACaptureRequest_setUserContext(req, (void*) capture);
            int seqId;
            ret = testCase.capture(req, &resultCb, &seqId);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
                        cameraId, capture, ret);
                goto cleanup;
            }
            if (capture == NUM_TEST_IMAGES - 1) {
                lastSeqId = seqId;
            }
            ACaptureRequest_free(req);
        }

        // wait until last sequence complete
        resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 5);

        std::vector<ACaptureRequest*> completedRequests;
        resultListener.getCompletedRequests(&completedRequests);

        if (completedRequests.size() != NUM_TEST_IMAGES) {
            LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
                    cameraId, NUM_TEST_IMAGES, completedRequests.size());
            goto cleanup;
        }

        for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
            intptr_t userContext = -1;
            ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
                goto cleanup;
            }

            if (userContext != i) {
                LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
                        "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
                goto cleanup;
            }
        }

        int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
                format, testWidth, testHeight);
        if (minFrameDurationNs < 0) {
            LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
            goto cleanup;
        }
        int64_t stallDurationNs = (format == AIMAGE_FORMAT_Y8) ? 0 :
                staticInfo.getStallDurationFor(format, testWidth, testHeight);
        if (stallDurationNs < 0) {
            LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
            goto cleanup;
        }

        int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
        constexpr int64_t waitPerIterationUs = 100000;
        constexpr int64_t usToNs = 1000;
        int totalWaitIteration = 50;

        // Allow 1.5x margin
        if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
            totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
        }

        // wait until all capture finished
        for (int i = 0; i < totalWaitIteration; i++) {
            usleep(waitPerIterationUs);
            if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
                ALOGI("Session take ~%d ms to capture %d images",
                        i*100, NUM_TEST_IMAGES);
                break;
            }
        }

        if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
            LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
                    cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
            goto cleanup;
        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(200000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;

cleanup:
    if (outPath != nullptr) {
        env->ReleaseStringUTFChars(jOutPath, outPath);
    }

    if (chars != nullptr) {
        ACameraMetadata_free(chars);
        chars = nullptr;
    }

    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

// Test the camera NDK capture failure path by acquiring the maximum amount of
// ImageReader buffers available. Since there is no circulation of camera
// images, the registered output surface will eventually run out of free buffers
// and start reporting capture errors or lost buffers.
extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
testCameraDeviceCaptureFailureNative(JNIEnv* env, jclass /*clazz*/, jstring jOverrideCameraId) {
    const size_t NUM_TEST_IMAGES = 10;
    const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
    const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
    const size_t TEST_WIDTH  = 640;
    const size_t TEST_HEIGHT = 480;
    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
    int numCameras = 0;
    bool pass = false;
    PreviewTestCase testCase;
    uint32_t bufferTimeoutSec = 1;
    uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
                              // timeout

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto exit;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
        goto exit;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto exit;
        }

        std::unique_ptr<ACameraMetadata> chars(testCase.getCameraChars(i));
        if (chars.get() == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
            goto exit;
        }
        StaticInfo staticInfo(chars.get());

        if (!staticInfo.isColorOutputSupported()) {
            continue;
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto exit;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto exit;
        }

        ImageReaderListener readerListener;
        AImageReader_ImageListener readerCb =
                { &readerListener, ImageReaderListener::signalImageCb };
        mediaRet = testCase.initImageReaderWithErrorLog(TEST_WIDTH, TEST_HEIGHT,
                AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES, &readerCb);
        if (mediaRet != AMEDIA_OK) {
            // Don't log error here. testcase did it
            goto exit;
        }

        ret = testCase.createCaptureSessionWithLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto exit;
        }

        ret = testCase.createRequestsWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto exit;
        }

        CaptureResultListener resultListener;
        ACameraCaptureSession_captureCallbacks resultCb {
            &resultListener,
            CaptureResultListener::onCaptureStart,
            CaptureResultListener::onCaptureProgressed,
            CaptureResultListener::onCaptureCompleted,
            CaptureResultListener::onCaptureFailed,
            CaptureResultListener::onCaptureSequenceCompleted,
            CaptureResultListener::onCaptureSequenceAborted,
            CaptureResultListener::onCaptureBufferLost
        };
        ACaptureRequest* requestTemplate = nullptr;
        ret = testCase.getStillRequest(&requestTemplate);
        if (ret != ACAMERA_OK || requestTemplate == nullptr) {
            // Don't log error here. testcase did it
            goto exit;
        }

        int seqId;
        ret = testCase.startRepeatingRequest(&seqId, requestTemplate, &resultCb);
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto exit;
        }

        size_t failedRequestCount;
        int64_t lastFrameNumber;
        int64_t lastFailedRequestNumber = -1;
        failedRequestCount = lastFrameNumber = 0;
        while ((failedRequestCount < NUM_FAILED_FRAMES) && (lastFrameNumber < NUM_TOTAL_FRAMES)) {
            auto frameArrived = resultListener.waitForFrameNumber(lastFrameNumber, timeoutSec);
            if (!frameArrived) {
                LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
                        cameraId);
                goto exit;
            }
            readerListener.waitForNextBuffer(bufferTimeoutSec);
            auto failedFrameNumber = resultListener.checkForFailureOrLoss(lastFrameNumber) ?
                    lastFrameNumber : -1;
            if (lastFailedRequestNumber != failedFrameNumber) {
                if ((lastFailedRequestNumber + 1) == failedFrameNumber) {
                    failedRequestCount++;
                } else {
                    failedRequestCount = 1;
                }
                lastFailedRequestNumber = failedFrameNumber;
            }
            lastFrameNumber++;
        }

        ret = testCase.abortCaptures();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "abort captures failed!");
            goto exit;
        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto exit;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto exit;
        }

        if (failedRequestCount < NUM_FAILED_FRAMES) {
            LOG_ERROR(errorString, "Unable to receive %zu consecutive capture failures within"
                    " %" PRId64 " capture requests", NUM_FAILED_FRAMES, NUM_TOTAL_FRAMES);
            goto exit;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto exit;
    }

    pass = true;

exit:

    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }

    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testJpegNative(
        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
            ImageReaderListener::validateImageCb, jOverrideCameraId);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testY8Native(
        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
            ImageReaderListener::validateImageCb, jOverrideCameraId);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testHeicNative(
        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
            ImageReaderListener::validateImageCb, jOverrideCameraId);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testDepthJpegNative(
        JNIEnv* env, jclass /*clazz*/, jstring jOutPath,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
            ImageReaderListener::validateImageCb, jOverrideCameraId);
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_\
testImageReaderCloseAcquiredImagesNative(
        JNIEnv* env, jclass /*clazz*/,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
            ImageReaderListener::acquireImageCb, jOverrideCameraId);
}

template <>
struct std::default_delete<ACameraManager> {
    inline void operator()(ACameraManager* manager) const { ACameraManager_delete(manager); }
};

class AvailabilityContext {
    public:
        AvailabilityContext();
        ~AvailabilityContext();

        camera_status_t initialize();
        int getAcessCallbackCountAndReset();

    private:
        std::unique_ptr<ACameraManager> mCameraManager;
        std::unique_ptr<CameraServiceListener> mServiceListener;
        std::unique_ptr<ACameraManager_ExtendedAvailabilityCallbacks> mServiceCb;
};

AvailabilityContext::AvailabilityContext() :
    mCameraManager(ACameraManager_create()),
    mServiceListener(std::make_unique<CameraServiceListener>()),
    mServiceCb(std::make_unique<ACameraManager_ExtendedAvailabilityCallbacks>()) {
        mServiceCb->availabilityCallbacks.context = mServiceListener.get();
        mServiceCb->availabilityCallbacks.onCameraAvailable = CameraServiceListener::onAvailable;
        mServiceCb->availabilityCallbacks.onCameraUnavailable =
                CameraServiceListener::onUnavailable;
        mServiceCb->onCameraAccessPrioritiesChanged =
                CameraServiceListener::onCameraAccessPrioritiesChanged;
        mServiceCb->onPhysicalCameraAvailable =
                CameraServiceListener::onPhysicalCameraAvailable;
        mServiceCb->onPhysicalCameraUnavailable =
                CameraServiceListener::onPhysicalCameraUnavailable;
}

camera_status_t AvailabilityContext::initialize() {
    auto rc = ACameraManager_registerExtendedAvailabilityCallback(mCameraManager.get(),
            mServiceCb.get());
    if (rc != ACAMERA_OK) {
        LOG_ERROR(errorString, "Register availability callback failed: rc %d", rc);
        return rc;
    }

    ACameraIdList* cameraIdList = nullptr;
    rc = ACameraManager_getCameraIdList(mCameraManager.get(), &cameraIdList);
    if (rc != ACAMERA_OK) {
        LOG_ERROR(errorString, "Get camera id list failed: ret %d", rc);
        return rc;
    }
    ACameraManager_deleteCameraIdList(cameraIdList);

    return rc;
}

int AvailabilityContext::getAcessCallbackCountAndReset() {
    auto ret = mServiceListener->getCameraAccessPrioritiesChangedCount();
    mServiceListener->resetCount();
    return ret;
}

AvailabilityContext::~AvailabilityContext() {
    if (mServiceCb != nullptr) {
        camera_status_t ret = ACameraManager_unregisterExtendedAvailabilityCallback(
                mCameraManager.get(), mServiceCb.get());
        if (ret != ACAMERA_OK) {
            ALOGE("Unregister availability callback failed: ret %d", ret);
        }
    }
}

extern "C" jlong
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
initializeAvailabilityCallbacksNative(
        JNIEnv* env, jclass /*clazz*/) {
    ALOGV("%s", __FUNCTION__);

    AvailabilityContext *ctx = new AvailabilityContext();

    auto rc = ctx->initialize();
    if (rc != ACAMERA_OK) {
        delete ctx;
        LOG_ERROR(errorString, "Availability context initialization failed: %d", rc);
        return 0;
    }

    return (jlong) ctx;
}

extern "C" jint
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
getAccessCallbacksCountAndResetNative(
        JNIEnv* env, jclass /*clazz*/, jlong context) {
    ALOGV("%s", __FUNCTION__);

    if (context == 0) {
        LOG_ERROR(errorString, "Invalid availability context");
        return 0;
    }

    AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
    return ctx->getAcessCallbackCountAndReset();
}

extern "C" void
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
releaseAvailabilityCallbacksNative(
        JNIEnv* env, jclass /*clazz*/, jlong context) {
    ALOGV("%s", __FUNCTION__);

    if (context == 0) {
        return;
    }

    AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
    delete ctx;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
testStillCaptureNative(
        JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface,
        jstring jOverrideCameraId) {
    ALOGV("%s", __FUNCTION__);
    const int NUM_TEST_IMAGES = 10;
    media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
    int numCameras = 0;
    bool pass = false;
    PreviewTestCase testCase;
    ACameraMetadata* chars = nullptr;

    const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
    ALOGI("%s: out path is %s", __FUNCTION__, outPath);

    camera_status_t ret = testCase.initWithErrorLog(env, jOverrideCameraId);
    if (ret != ACAMERA_OK) {
        // Don't log error here. testcase did it
        goto cleanup;
    }

    numCameras = testCase.getNumCameras();
    if (numCameras < 0) {
        LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
        goto cleanup;
    }

    for (int i = 0; i < numCameras; i++) {
        const char* cameraId = testCase.getCameraId(i);
        if (cameraId == nullptr) {
            LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
            goto cleanup;
        }

        {
            ACameraMetadata* chars = testCase.getCameraChars(cameraId);
            StaticInfo staticInfo(chars);
            if (!staticInfo.isColorOutputSupported()) {
                ALOGI("%s: camera %s does not support color output. skipping",
                        __FUNCTION__, cameraId);
                ACameraMetadata_free(chars);
                continue;
            }
            ACameraMetadata_free(chars);
        }

        ret = testCase.openCamera(cameraId);
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
            goto cleanup;
        }

        chars = testCase.getCameraChars(i);
        if (chars == nullptr) {
            LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
            goto cleanup;
        }
        StaticInfo staticInfo(chars);

        usleep(100000); // sleep to give some time for callbacks to happen

        if (testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
            goto cleanup;
        }

        ImageReaderListener readerListener;
        AImageReader_ImageListener readerCb {
            &readerListener,
            ImageReaderListener::validateImageCb
        };
        readerListener.setDumpFilePathBase(outPath);
        int32_t testWidth, testHeight;
        if (!staticInfo.getMaxSizeForFormat(AIMAGE_FORMAT_JPEG, &testWidth, &testHeight)) {
            goto cleanup;
        }
        mediaRet = testCase.initImageReaderWithErrorLog(
                testWidth, testHeight, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
                &readerCb);
        if (mediaRet != AMEDIA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
        if (previewAnw == nullptr) {
            LOG_ERROR(errorString, "Null ANW from preview surface!");
            goto cleanup;
        }

        ret = testCase.createCaptureSessionWithLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.createRequestsWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        ret = testCase.startPreview();
        if (ret != ACAMERA_OK) {
            LOG_ERROR(errorString, "Start preview failed!");
            goto cleanup;
        }

        // Let preview run some time
        sleep(3);

        // Do some still capture
        for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
            ret = testCase.takePicture();
            if (ret != ACAMERA_OK) {
                LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
                        cameraId, capture, ret);
                goto cleanup;
            }
        }

        int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
                AIMAGE_FORMAT_JPEG, testWidth, testHeight);
        if (minFrameDurationNs < 0) {
            LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
            goto cleanup;
        }
        int64_t stallDurationNs = staticInfo.getStallDurationFor(
                AIMAGE_FORMAT_JPEG, testWidth, testHeight);
        if (stallDurationNs < 0) {
            LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
            goto cleanup;
        }

        int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
        constexpr int64_t waitPerIterationUs = 100000;
        constexpr int64_t usToNs = 1000;
        int totalWaitIteration = 60;

        // Allow 1.5x margin
        if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
            totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
        }

        // wait until all capture finished
        for (int i = 0; i < totalWaitIteration; i++) {
            usleep(waitPerIterationUs);
            if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
                ALOGI("Session take ~%d ms to capture %d images",
                        i*100, NUM_TEST_IMAGES);
                break;
            }
        }

        if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
            LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
                    cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
            testCase.resetWithErrorLog();
            goto cleanup;
        }

        ret = testCase.resetWithErrorLog();
        if (ret != ACAMERA_OK) {
            // Don't log error here. testcase did it
            goto cleanup;
        }

        usleep(100000); // sleep to give some time for callbacks to happen

        if (!testCase.isCameraAvailable(cameraId)) {
            LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
            goto cleanup;
        }
    }

    ret = testCase.deInit();
    if (ret != ACAMERA_OK) {
        LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
        goto cleanup;
    }

    pass = true;
cleanup:
    env->ReleaseStringUTFChars(jOutPath, outPath);

    if (chars != nullptr) {
        ACameraMetadata_free(chars);
        chars = nullptr;
    }

    ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    if (!pass) {
        throwAssertionError(env, errorString);
    }
    return pass;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_\
validateACameraMetadataFromCameraMetadataCriticalTagsNative(
        JNIEnv* env, jclass /*clazz*/, jobject captureResult,
        jlong javaTimestamp) {
    ALOGV("%s", __FUNCTION__);
    ACameraMetadata* ndkResult =
        ACameraMetadata_fromCameraMetadata(env, captureResult);
    if (!ndkResult) {
        ALOGE("validateCriticalTags failed: "
              "ACameraMetadata_fromCameraMetadata returned nullptr.");
        return false;
    }

    camera_status_t ret;
    ACameraMetadata_const_entry entry;

    ret = ACameraMetadata_getConstEntry(ndkResult, ACAMERA_SENSOR_TIMESTAMP,
        &entry);

    if (ret != ACAMERA_OK) {
        ALOGE("validateCriticalTags failed: "
              "ACameraMetadata_getConstEntry returned %d.", ret);
        ACameraMetadata_free(ndkResult);
        return false;
    }
    if (entry.type != ACAMERA_TYPE_INT64) {
        ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
              entry.type, ACAMERA_TYPE_INT64);
        ACameraMetadata_free(ndkResult);
        return false;
    }
    if (entry.count != 1) {
        ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
              entry.count, 1);
        ACameraMetadata_free(ndkResult);
        return false;
    }
    if (entry.data.i64 == nullptr) {
        ALOGE("validateCriticalTags failed: entry.data.i64 is nullptr.");
        ACameraMetadata_free(ndkResult);
        return false;
    }

    const int64_t javaTimestampI64 = static_cast<int64_t>(javaTimestamp);
    const int64_t ndkTimestampI64 = *(entry.data.i64);
    ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
          javaTimestampI64, ndkTimestampI64);

    ACameraMetadata_free(ndkResult);

    return (javaTimestampI64 == ndkTimestampI64);
}

static ACameraMetadata *sStashedMetadata = nullptr;

// Test holding on to a ACameraMetadata past a single local JNI call
extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_\
stashACameraMetadataFromCameraMetadataNative(
        JNIEnv* env, jclass /*clazz*/, jobject captureResult) {
    ALOGV("%s", __FUNCTION__);
    ACameraMetadata* ndkResult =
        ACameraMetadata_fromCameraMetadata(env, captureResult);
    if (ndkResult == nullptr) return false;
    sStashedMetadata = ndkResult;

    return true;
}

extern "C" jboolean
Java_android_hardware_camera2_cts_CaptureResultTest_\
validateStashedACameraMetadataFromCameraMetadataNative(
        JNIEnv* env, jclass /*clazz*/, jlong timestamp) {
    ALOGV("%s", __FUNCTION__);
    if (sStashedMetadata == nullptr) return false;

    camera_status_t ret;
    ACameraMetadata_const_entry entry;

    ret = ACameraMetadata_getConstEntry(sStashedMetadata, ACAMERA_SENSOR_TIMESTAMP,
        &entry);

    if (ret != ACAMERA_OK) {
        ALOGE("validateStashed failed: "
              "ACameraMetadata_getConstEntry returned %d.", ret);
        ACameraMetadata_free(sStashedMetadata);
        sStashedMetadata = nullptr;
        return false;
    }
    if (entry.type != ACAMERA_TYPE_INT64) {
        ALOGE("validateStashed failed: entry.type is %u but should be %u.",
              entry.type, ACAMERA_TYPE_INT64);
        ACameraMetadata_free(sStashedMetadata);
        sStashedMetadata = nullptr;
        return false;
    }
    if (entry.count != 1) {
        ALOGE("validateStashed failed: entry.count is %u but should be %u.",
              entry.count, 1);
        ACameraMetadata_free(sStashedMetadata);
        sStashedMetadata = nullptr;
        return false;
    }
    if (entry.data.i64 == nullptr) {
        ALOGE("validateStashed failed: entry.data.i64 is nullptr.");
        ACameraMetadata_free(sStashedMetadata);
        sStashedMetadata = nullptr;
        return false;
    }

    const int64_t javaTimestampI64 = static_cast<int64_t>(timestamp);
    const int64_t ndkTimestampI64 = *(entry.data.i64);

    ACameraMetadata_free(sStashedMetadata);
    sStashedMetadata = nullptr;
    ALOGV("javaTimestampI64 = %" PRId64 ", ndkTimestampI64 = %" PRId64,
          javaTimestampI64, ndkTimestampI64);
    return (javaTimestampI64 == ndkTimestampI64);

}



extern "C" jboolean
Java_android_hardware_camera2_cts_CameraManagerTest_\
validateACameraMetadataFromCameraMetadataCriticalTagsNative(
        JNIEnv* env, jclass /*clazz*/, jobject cameraCharacteristics,
        jint javaLensFacing) {
    ALOGV("%s", __FUNCTION__);
    ACameraMetadata* ndkCharacteristics =
        ACameraMetadata_fromCameraMetadata(env, cameraCharacteristics);
    if (!ndkCharacteristics) {
        ALOGE("validateCriticalTags failed: "
              "ACameraMetadata_fromCameraMetadata returned nullptr.");
        return false;
    }

    camera_status_t ret;
    ACameraMetadata_const_entry entry;

    ret = ACameraMetadata_getConstEntry(ndkCharacteristics,
        ACAMERA_LENS_FACING, &entry);
    ACameraMetadata_free(ndkCharacteristics);

    if (ret != ACAMERA_OK) {
        ALOGE("validateCriticalTags failed: "
              "ACameraMetadata_getConstEntry returned %d", ret);
        return false;
    }
    if (entry.type != ACAMERA_TYPE_BYTE) {
        ALOGE("validateCriticalTags failed: entry.type is %u but should be %u.",
              entry.type, ACAMERA_TYPE_BYTE);
        return false;
    }
    if (entry.count != 1) {
        ALOGE("validateCriticalTags failed: entry.count is %u but should be %u.",
              entry.count, 1);
        return false;
    }
    if (entry.data.u8 == nullptr) {
        ALOGE("validateCriticalTags failed: entry.data.u8 is nullptr.");
        return false;
    }

    const uint8_t javaLensFacingU8 = static_cast<uint8_t>(javaLensFacing);
    const uint8_t ndkLensFacingU8 = *(entry.data.u8);
    ALOGV("javaLensFacingU8 = %d, ndkLensFacingU8 = %d",
          javaLensFacingU8, ndkLensFacingU8);
    return (javaLensFacingU8 == ndkLensFacingU8);
}
