Home | History | Annotate | Download | only in libctscamera2jni
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "NativeCamera"
     19 #include <log/log.h>
     20 
     21 #include <string>
     22 #include <map>
     23 #include <mutex>
     24 #include <unistd.h>
     25 #include <assert.h>
     26 #include <jni.h>
     27 #include <stdio.h>
     28 #include <string.h>
     29 
     30 #include <android/native_window_jni.h>
     31 
     32 #include "NdkCameraError.h"
     33 #include "NdkCameraManager.h"
     34 #include "NdkCameraDevice.h"
     35 #include "NdkCameraCaptureSession.h"
     36 #include "NdkImage.h"
     37 #include "NdkImageReader.h"
     38 
     39 #define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
     40                             ALOGE("%s", buf);
     41 
     42 namespace {
     43     const int MAX_ERROR_STRING_LEN = 512;
     44     char errorString[MAX_ERROR_STRING_LEN];
     45 }
     46 
     47 class CameraServiceListener {
     48   public:
     49     static void onAvailable(void* obj, const char* cameraId) {
     50         ALOGV("Camera %s onAvailable", cameraId);
     51         if (obj == nullptr) {
     52             return;
     53         }
     54         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
     55         std::lock_guard<std::mutex> lock(thiz->mMutex);
     56         thiz->mOnAvailableCount++;
     57         thiz->mAvailableMap[cameraId] = true;
     58         return;
     59     }
     60 
     61     static void onUnavailable(void* obj, const char* cameraId) {
     62         ALOGV("Camera %s onUnavailable", cameraId);
     63         if (obj == nullptr) {
     64             return;
     65         }
     66         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
     67         std::lock_guard<std::mutex> lock(thiz->mMutex);
     68         thiz->mOnUnavailableCount++;
     69         thiz->mAvailableMap[cameraId] = false;
     70         return;
     71     }
     72 
     73     void resetCount() {
     74         std::lock_guard<std::mutex> lock(mMutex);
     75         mOnAvailableCount = 0;
     76         mOnUnavailableCount = 0;
     77         return;
     78     }
     79 
     80     int getAvailableCount() {
     81         std::lock_guard<std::mutex> lock(mMutex);
     82         return mOnAvailableCount;
     83     }
     84 
     85     int getUnavailableCount() {
     86         std::lock_guard<std::mutex> lock(mMutex);
     87         return mOnUnavailableCount;
     88     }
     89 
     90     bool isAvailable(const char* cameraId) {
     91         std::lock_guard<std::mutex> lock(mMutex);
     92         if (mAvailableMap.count(cameraId) == 0) {
     93             return false;
     94         }
     95         return mAvailableMap[cameraId];
     96     }
     97 
     98   private:
     99     std::mutex mMutex;
    100     int mOnAvailableCount = 0;
    101     int mOnUnavailableCount = 0;
    102     std::map<std::string, bool> mAvailableMap;
    103 };
    104 
    105 class CameraDeviceListener {
    106   public:
    107     static void onDisconnected(void* obj, ACameraDevice* device) {
    108         ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
    109         if (obj == nullptr) {
    110             return;
    111         }
    112         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
    113         std::lock_guard<std::mutex> lock(thiz->mMutex);
    114         thiz->mOnDisconnect++;
    115         return;
    116     }
    117 
    118     static void onError(void* obj, ACameraDevice* device, int errorCode) {
    119         ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
    120         if (obj == nullptr) {
    121             return;
    122         }
    123         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
    124         std::lock_guard<std::mutex> lock(thiz->mMutex);
    125         thiz->mOnError++;
    126         thiz->mLatestError = errorCode;
    127         return;
    128     }
    129 
    130   private:
    131     std::mutex mMutex;
    132     int mOnDisconnect = 0;
    133     int mOnError = 0;
    134     int mLatestError = 0;
    135 };
    136 
    137 class CaptureSessionListener {
    138 
    139   public:
    140     static void onClosed(void* obj, ACameraCaptureSession *session) {
    141         // TODO: might want an API to query cameraId even session is closed?
    142         ALOGV("Session %p is closed!", session);
    143         if (obj == nullptr) {
    144             return;
    145         }
    146         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
    147         std::lock_guard<std::mutex> lock(thiz->mMutex);
    148         thiz->mIsClosed = true;
    149         thiz->mOnClosed++; // Should never > 1
    150     }
    151 
    152     static void onReady(void* obj, ACameraCaptureSession *session) {
    153         ALOGV("%s", __FUNCTION__);
    154         if (obj == nullptr) {
    155             return;
    156         }
    157         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
    158         std::lock_guard<std::mutex> lock(thiz->mMutex);
    159         ACameraDevice* device = nullptr;
    160         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
    161         // There will be one onReady fired after session closed
    162         if (ret != ACAMERA_OK && !thiz->mIsClosed) {
    163             ALOGE("%s Getting camera device from session callback failed!",
    164                     __FUNCTION__);
    165             thiz->mInError = true;
    166         }
    167         ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
    168         thiz->mIsIdle = true;
    169         thiz->mOnReady++;
    170     }
    171 
    172     static void onActive(void* obj, ACameraCaptureSession *session) {
    173         ALOGV("%s", __FUNCTION__);
    174         if (obj == nullptr) {
    175             return;
    176         }
    177         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
    178         std::lock_guard<std::mutex> lock(thiz->mMutex);
    179         ACameraDevice* device = nullptr;
    180         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
    181         if (ret != ACAMERA_OK) {
    182             ALOGE("%s Getting camera device from session callback failed!",
    183                     __FUNCTION__);
    184             thiz->mInError = true;
    185         }
    186         ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
    187         thiz->mIsIdle = false;
    188         thiz->mOnActive;
    189     }
    190 
    191     bool isClosed() {
    192         std::lock_guard<std::mutex> lock(mMutex);
    193         return mIsClosed;
    194     }
    195 
    196     bool isIdle() {
    197         std::lock_guard<std::mutex> lock(mMutex);
    198         return mIsIdle;
    199     }
    200 
    201     bool isInError() {
    202         std::lock_guard<std::mutex> lock(mMutex);
    203         return mInError;
    204     }
    205 
    206     int onClosedCount()  {
    207         std::lock_guard<std::mutex> lock(mMutex);
    208         return mOnClosed;
    209     }
    210 
    211     int onReadyCount()  {
    212         std::lock_guard<std::mutex> lock(mMutex);
    213         return mOnReady;
    214     }
    215 
    216     int onActiveCount()  {
    217         std::lock_guard<std::mutex> lock(mMutex);
    218         return mOnActive;
    219     }
    220 
    221     void reset() {
    222         std::lock_guard<std::mutex> lock(mMutex);
    223         mIsClosed = false;
    224         mIsIdle = true;
    225         mInError = false;
    226         mOnClosed = 0;
    227         mOnReady = 0;
    228         mOnActive = 0;
    229     }
    230 
    231   private:
    232     std::mutex mMutex;
    233     bool mIsClosed = false;
    234     bool mIsIdle = true;
    235     bool mInError = false; // should always stay false
    236     int mOnClosed = 0;
    237     int mOnReady = 0;
    238     int mOnActive = 0;
    239 };
    240 
    241 class ImageReaderListener {
    242   public:
    243     static void onImageAvailable(void* obj, AImageReader* reader) {
    244         ALOGV("%s", __FUNCTION__);
    245         if (obj == nullptr) {
    246             return;
    247         }
    248         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
    249         std::lock_guard<std::mutex> lock(thiz->mMutex);
    250         thiz->mOnImageAvailableCount++;
    251 
    252         AImage* img = nullptr;
    253         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
    254         if (ret != AMEDIA_OK || img == nullptr) {
    255             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
    256                     __FUNCTION__, reader, ret, img);
    257             return;
    258         }
    259 
    260         // TODO: validate image content
    261         int32_t format = -1;
    262         ret = AImage_getFormat(img, &format);
    263         if (ret != AMEDIA_OK || format == -1) {
    264             ALOGE("%s: get format for image %p failed! ret: %d, format %d",
    265                     __FUNCTION__, img, ret, format);
    266         }
    267 
    268         // Save jpeg to SD card
    269         if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
    270             int32_t numPlanes = 0;
    271             ret = AImage_getNumberOfPlanes(img, &numPlanes);
    272             if (ret != AMEDIA_OK || numPlanes != 1) {
    273                 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
    274                         __FUNCTION__, img, ret, numPlanes);
    275                 AImage_delete(img);
    276                 return;
    277             }
    278 
    279             int32_t width = -1, height = -1;
    280             ret = AImage_getWidth(img, &width);
    281             if (ret != AMEDIA_OK || width <= 0) {
    282                 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
    283                         __FUNCTION__, img, ret, width);
    284                 AImage_delete(img);
    285                 return;
    286             }
    287 
    288             ret = AImage_getHeight(img, &height);
    289             if (ret != AMEDIA_OK || height <= 0) {
    290                 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
    291                         __FUNCTION__, img, ret, height);
    292                 AImage_delete(img);
    293                 return;
    294             }
    295 
    296             uint8_t* data = nullptr;
    297             int dataLength = 0;
    298             ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
    299             if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
    300                 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
    301                         __FUNCTION__, img, ret, data, dataLength);
    302                 AImage_delete(img);
    303                 return;
    304             }
    305 
    306 #if 0
    307             char dumpFilePath[512];
    308             sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
    309             ALOGI("Writing jpeg file to %s", dumpFilePath);
    310             FILE* file = fopen(dumpFilePath,"w+");
    311 
    312             if (file != nullptr) {
    313                 fwrite(data, 1, dataLength, file);
    314                 fflush(file);
    315                 fclose(file);
    316             }
    317 #endif
    318         }
    319 
    320         AImage_delete(img);
    321     }
    322 
    323     int onImageAvailableCount() {
    324         std::lock_guard<std::mutex> lock(mMutex);
    325         return mOnImageAvailableCount;
    326     }
    327 
    328     void setDumpFilePathBase(const char* path) {
    329         std::lock_guard<std::mutex> lock(mMutex);
    330         mDumpFilePathBase = path;
    331     }
    332 
    333     void reset() {
    334         std::lock_guard<std::mutex> lock(mMutex);
    335         mOnImageAvailableCount = 0;
    336         mDumpFilePathBase = nullptr;
    337     }
    338 
    339   private:
    340     // TODO: add mReader to make sure each listener is associated to one reader?
    341     std::mutex mMutex;
    342     int mOnImageAvailableCount = 0;
    343     const char* mDumpFilePathBase = nullptr;
    344 };
    345 
    346 class StaticInfo {
    347   public:
    348     StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
    349 
    350     bool isColorOutputSupported() {
    351         return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
    352     }
    353 
    354     bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
    355         ACameraMetadata_const_entry entry;
    356         ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
    357         for (uint32_t i = 0; i < entry.count; i++) {
    358             if (entry.data.u8[i] == cap) {
    359                 return true;
    360             }
    361         }
    362         return false;
    363     }
    364   private:
    365     const ACameraMetadata* mChars;
    366 };
    367 
    368 class PreviewTestCase {
    369   public:
    370     ~PreviewTestCase() {
    371         resetCamera();
    372         deInit();
    373         if (mCameraManager) {
    374             ACameraManager_delete(mCameraManager);
    375             mCameraManager = nullptr;
    376         }
    377     }
    378 
    379     PreviewTestCase() {
    380         // create is guaranteed to succeed;
    381         createManager();
    382     }
    383 
    384     // Free all resources except camera manager
    385     void resetCamera() {
    386         mReaderListener.reset();
    387         mSessionListener.reset();
    388         if (mSession) {
    389             ACameraCaptureSession_close(mSession);
    390             mSession = nullptr;
    391         }
    392         if (mDevice) {
    393             ACameraDevice_close(mDevice);
    394             mDevice = nullptr;
    395         }
    396         if (mImgReader) {
    397             AImageReader_delete(mImgReader);
    398             // No need to call ANativeWindow_release on imageReaderAnw
    399             mImgReaderAnw = nullptr;
    400             mImgReader = nullptr;
    401         }
    402         if (mPreviewAnw) {
    403             ANativeWindow_release(mPreviewAnw);
    404             mPreviewAnw = nullptr;
    405         }
    406         if (mOutputs) {
    407             ACaptureSessionOutputContainer_free(mOutputs);
    408             mOutputs = nullptr;
    409         }
    410         if (mPreviewOutput) {
    411             ACaptureSessionOutput_free(mPreviewOutput);
    412             mPreviewOutput = nullptr;
    413         }
    414         if (mImgReaderOutput) {
    415             ACaptureSessionOutput_free(mImgReaderOutput);
    416             mImgReaderOutput = nullptr;
    417         }
    418         if (mPreviewRequest) {
    419             ACaptureRequest_free(mPreviewRequest);
    420             mPreviewRequest = nullptr;
    421         }
    422         if (mStillRequest) {
    423             ACaptureRequest_free(mStillRequest);
    424             mStillRequest = nullptr;
    425         }
    426         if (mReqPreviewOutput) {
    427             ACameraOutputTarget_free(mReqPreviewOutput);
    428             mReqPreviewOutput = nullptr;
    429         }
    430         if (mReqImgReaderOutput) {
    431             ACameraOutputTarget_free(mReqImgReaderOutput);
    432             mReqImgReaderOutput = nullptr;
    433         }
    434 
    435         mImgReaderInited = false;
    436         mPreviewInited = false;
    437     }
    438 
    439     camera_status_t initWithErrorLog() {
    440         camera_status_t ret = ACameraManager_getCameraIdList(
    441                 mCameraManager, &mCameraIdList);
    442         if (ret != ACAMERA_OK) {
    443             LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
    444             return ret;
    445         }
    446         ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
    447         if (ret != ACAMERA_OK) {
    448             LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
    449             return ret;
    450         }
    451         mMgrInited = true;
    452         return ACAMERA_OK;
    453     }
    454 
    455     camera_status_t deInit () {
    456         if (!mMgrInited) {
    457             return ACAMERA_OK;
    458         }
    459 
    460         camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
    461                 mCameraManager, &mServiceCb);
    462         if (ret != ACAMERA_OK) {
    463             ALOGE("Unregister availability callback failed: ret %d", ret);
    464             return ret;
    465         }
    466 
    467         if (mCameraIdList) {
    468             ACameraManager_deleteCameraIdList(mCameraIdList);
    469             mCameraIdList = nullptr;
    470         }
    471         mMgrInited = false;
    472         return ACAMERA_OK;
    473     }
    474 
    475     int getNumCameras() {
    476         if (!mMgrInited || !mCameraIdList) {
    477             return -1;
    478         }
    479         return mCameraIdList->numCameras;
    480     }
    481 
    482     const char* getCameraId(int idx) {
    483         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
    484             return nullptr;
    485         }
    486         return mCameraIdList->cameraIds[idx];
    487     }
    488 
    489     camera_status_t openCamera(const char* cameraId) {
    490         if (mDevice) {
    491             ALOGE("Cannot open camera before closing previously open one");
    492             return ACAMERA_ERROR_INVALID_PARAMETER;
    493         }
    494         mCameraId = cameraId;
    495         return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
    496     }
    497 
    498     camera_status_t closeCamera() {
    499         camera_status_t ret = ACameraDevice_close(mDevice);
    500         mDevice = nullptr;
    501         return ret;
    502     }
    503 
    504     bool isCameraAvailable(const char* cameraId) {
    505         if (!mMgrInited) {
    506             ALOGE("Camera service listener has not been registered!");
    507         }
    508         return mServiceListener.isAvailable(cameraId);
    509     }
    510 
    511     media_status_t initImageReaderWithErrorLog(
    512             int32_t width, int32_t height, int32_t format, int32_t maxImages) {
    513         if (mImgReader || mImgReaderAnw) {
    514             LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
    515             return AMEDIA_ERROR_UNKNOWN;
    516         }
    517 
    518         media_status_t ret = AImageReader_new(
    519                 width, height, format,
    520                 maxImages, &mImgReader);
    521         if (ret != AMEDIA_OK) {
    522             LOG_ERROR(errorString, "Create image reader. ret %d", ret);
    523             return ret;
    524         }
    525         if (mImgReader == nullptr) {
    526             LOG_ERROR(errorString, "null image reader created");
    527             return AMEDIA_ERROR_UNKNOWN;
    528         }
    529 
    530         ret = AImageReader_setImageListener(
    531                 mImgReader, &mReaderCb);
    532         if (ret != AMEDIA_OK) {
    533             LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
    534             return ret;
    535         }
    536 
    537         ret = AImageReader_getWindow(mImgReader, &mImgReaderAnw);
    538         if (ret != AMEDIA_OK) {
    539             LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
    540             return ret;
    541         }
    542         if (mImgReaderAnw == nullptr) {
    543             LOG_ERROR(errorString, "Null ANW from AImageReader!");
    544             return AMEDIA_ERROR_UNKNOWN;
    545         }
    546         mImgReaderInited = true;
    547         return AMEDIA_OK;
    548     }
    549 
    550     ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
    551         if (mPreviewAnw) {
    552             ALOGE("Cannot init preview twice!");
    553             return nullptr;
    554         }
    555         mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
    556         mPreviewInited = true;
    557         return mPreviewAnw;
    558     }
    559 
    560     camera_status_t createCaptureSessionWithLog() {
    561         if (mSession) {
    562             LOG_ERROR(errorString, "Cannot create session before closing existing one");
    563             return ACAMERA_ERROR_UNKNOWN;
    564         }
    565 
    566         if (!mMgrInited || (!mImgReaderInited && !mPreviewInited)) {
    567             LOG_ERROR(errorString, "Cannot create session. mgrInit %d readerInit %d previewInit %d",
    568                     mMgrInited, mImgReaderInited, mPreviewInited);
    569             return ACAMERA_ERROR_UNKNOWN;
    570         }
    571 
    572         camera_status_t ret = ACaptureSessionOutputContainer_create(&mOutputs);
    573         if (ret != ACAMERA_OK) {
    574             LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
    575             return ret;
    576         }
    577 
    578         if (mImgReaderInited) {
    579             ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
    580             if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
    581                 LOG_ERROR(errorString,
    582                         "Sesssion image reader output create fail! ret %d output %p",
    583                         ret, mImgReaderOutput);
    584                 if (ret == ACAMERA_OK) {
    585                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
    586                 }
    587                 return ret;
    588             }
    589 
    590             ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
    591             if (ret != ACAMERA_OK) {
    592                 LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
    593                 return ret;
    594             }
    595         }
    596 
    597         if (mPreviewInited) {
    598             ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
    599             if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
    600                 LOG_ERROR(errorString,
    601                         "Sesssion preview output create fail! ret %d output %p",
    602                         ret, mPreviewOutput);
    603                 if (ret == ACAMERA_OK) {
    604                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
    605                 }
    606                 return ret;
    607             }
    608 
    609             ret = ACaptureSessionOutputContainer_add(mOutputs, mPreviewOutput);
    610             if (ret != ACAMERA_OK) {
    611                 LOG_ERROR(errorString, "Sesssion preview output add failed! ret %d", ret);
    612                 return ret;
    613             }
    614         }
    615 
    616         ret = ACameraDevice_createCaptureSession(
    617                 mDevice, mOutputs, &mSessionCb, &mSession);
    618         if (ret != ACAMERA_OK || mSession == nullptr) {
    619             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
    620                     mCameraId, ret, mSession);
    621             if (ret == ACAMERA_OK) {
    622                 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
    623             }
    624             return ret;
    625         }
    626 
    627         return ACAMERA_OK;
    628     }
    629 
    630     void closeSession() {
    631         if (mSession != nullptr) {
    632             ACameraCaptureSession_close(mSession);
    633         }
    634         if (mOutputs) {
    635             ACaptureSessionOutputContainer_free(mOutputs);
    636             mOutputs = nullptr;
    637         }
    638         if (mPreviewOutput) {
    639             ACaptureSessionOutput_free(mPreviewOutput);
    640             mPreviewOutput = nullptr;
    641         }
    642         if (mImgReaderOutput) {
    643             ACaptureSessionOutput_free(mImgReaderOutput);
    644             mImgReaderOutput = nullptr;
    645         }
    646         mSession = nullptr;
    647     }
    648 
    649     camera_status_t createRequestsWithErrorLog() {
    650         if (mPreviewRequest || mStillRequest) {
    651             LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
    652             return ACAMERA_ERROR_UNKNOWN;
    653         }
    654 
    655         if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
    656             LOG_ERROR(errorString,
    657                     "Cannot create request. device %p previewInit %d readeInit %d",
    658                     mDevice, mPreviewInited, mImgReaderInited);
    659             return ACAMERA_ERROR_UNKNOWN;
    660         }
    661 
    662         camera_status_t ret;
    663         if (mPreviewInited) {
    664             ret = ACameraDevice_createCaptureRequest(
    665                     mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
    666             if (ret != ACAMERA_OK) {
    667                 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
    668                         mCameraId, ret);
    669                 return ret;
    670             }
    671 
    672             ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
    673             if (ret != ACAMERA_OK) {
    674                 LOG_ERROR(errorString,
    675                         "Camera %s create request preview output target failed. ret %d",
    676                         mCameraId, ret);
    677                 return ret;
    678             }
    679 
    680             ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
    681             if (ret != ACAMERA_OK) {
    682                 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
    683                         mCameraId, ret);
    684                 return ret;
    685             }
    686         } else {
    687             ALOGI("Preview not inited. Will not create preview request!");
    688         }
    689 
    690         if (mImgReaderInited) {
    691             ret = ACameraDevice_createCaptureRequest(
    692                     mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
    693             if (ret != ACAMERA_OK) {
    694                 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
    695                         mCameraId, ret);
    696                 return ret;
    697             }
    698 
    699             ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
    700             if (ret != ACAMERA_OK) {
    701                 LOG_ERROR(errorString,
    702                         "Camera %s create request reader output target failed. ret %d",
    703                         mCameraId, ret);
    704                 return ret;
    705             }
    706 
    707             ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
    708             if (ret != ACAMERA_OK) {
    709                 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
    710                         mCameraId, ret);
    711                 return ret;
    712             }
    713 
    714             if (mPreviewInited) {
    715                 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
    716                 if (ret != ACAMERA_OK) {
    717                     LOG_ERROR(errorString,
    718                             "Camera %s add still request preview output failed. ret %d",
    719                             mCameraId, ret);
    720                     return ret;
    721                 }
    722             }
    723         } else {
    724             ALOGI("AImageReader not inited. Will not create still request!");
    725         }
    726 
    727         return ACAMERA_OK;
    728     }
    729 
    730     camera_status_t startPreview() {
    731         if (mSession == nullptr || mPreviewRequest == nullptr) {
    732             ALOGE("Testcase cannot start preview: session %p, preview request %p",
    733                     mSession, mPreviewRequest);
    734             return ACAMERA_ERROR_UNKNOWN;
    735         }
    736         int previewSeqId;
    737         return ACameraCaptureSession_setRepeatingRequest(
    738                 mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
    739     }
    740 
    741     camera_status_t takePicture() {
    742         if (mSession == nullptr || mStillRequest == nullptr) {
    743             ALOGE("Testcase cannot take picture: session %p, still request %p",
    744                     mSession, mStillRequest);
    745             return ACAMERA_ERROR_UNKNOWN;
    746         }
    747         int seqId;
    748         return ACameraCaptureSession_capture(
    749                 mSession, nullptr, 1, &mStillRequest, &seqId);
    750     }
    751 
    752     int getReaderImageCount() {
    753         return mReaderListener.onImageAvailableCount();
    754     }
    755 
    756     camera_status_t resetWithErrorLog() {
    757         camera_status_t ret;
    758 
    759         mReaderListener.reset();
    760         closeSession();
    761 
    762         for (int i = 0; i < 50; i++) {
    763             usleep(100000); // sleep 100ms
    764             if (mSessionListener.isClosed()) {
    765                 ALOGI("Session take ~%d ms to close", i*100);
    766                 break;
    767             }
    768         }
    769 
    770         if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
    771             LOG_ERROR(errorString,
    772                     "Session for camera %s close error. isClosde %d close count %d",
    773                     mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
    774             return ACAMERA_ERROR_UNKNOWN;
    775         }
    776         mSessionListener.reset();
    777 
    778         ret = closeCamera();
    779         if (ret != ACAMERA_OK) {
    780             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
    781             return ret;
    782         }
    783 
    784         resetCamera();
    785         return ACAMERA_OK;
    786     }
    787 
    788     void setDumpFilePathBase(const char* path) {
    789         mReaderListener.setDumpFilePathBase(path);
    790     }
    791 
    792     CaptureSessionListener* getSessionListener() {
    793         return &mSessionListener;
    794     }
    795 
    796   private:
    797     ACameraManager* createManager() {
    798         if (!mCameraManager) {
    799             mCameraManager = ACameraManager_create();
    800         }
    801         return mCameraManager;
    802     }
    803 
    804     CameraServiceListener mServiceListener;
    805     ACameraManager_AvailabilityCallbacks mServiceCb {
    806         &mServiceListener,
    807         CameraServiceListener::onAvailable,
    808         CameraServiceListener::onUnavailable
    809     };
    810     CameraDeviceListener mDeviceListener;
    811     ACameraDevice_StateCallbacks mDeviceCb {
    812         &mDeviceListener,
    813         CameraDeviceListener::onDisconnected,
    814         CameraDeviceListener::onError
    815     };
    816     CaptureSessionListener mSessionListener;
    817     ACameraCaptureSession_stateCallbacks mSessionCb {
    818         &mSessionListener,
    819         CaptureSessionListener::onClosed,
    820         CaptureSessionListener::onReady,
    821         CaptureSessionListener::onActive
    822     };
    823 
    824     // TODO: capture listeners
    825     ImageReaderListener mReaderListener;
    826     AImageReader_ImageListener mReaderCb {
    827         &mReaderListener,
    828         ImageReaderListener::onImageAvailable
    829     };
    830 
    831     ACameraIdList* mCameraIdList = nullptr;
    832     ACameraDevice* mDevice = nullptr;
    833     AImageReader* mImgReader = nullptr;
    834     ANativeWindow* mImgReaderAnw = nullptr;
    835     ANativeWindow* mPreviewAnw = nullptr;
    836     ACameraManager* mCameraManager = nullptr;
    837     ACaptureSessionOutputContainer* mOutputs = nullptr;
    838     ACaptureSessionOutput* mPreviewOutput = nullptr;
    839     ACaptureSessionOutput* mImgReaderOutput = nullptr;
    840     ACameraCaptureSession* mSession = nullptr;
    841     ACaptureRequest* mPreviewRequest = nullptr;
    842     ACaptureRequest* mStillRequest = nullptr;
    843     ACameraOutputTarget* mReqPreviewOutput = nullptr;
    844     ACameraOutputTarget* mReqImgReaderOutput = nullptr;
    845     const char* mCameraId;
    846 
    847     bool mMgrInited = false; // cameraId, serviceListener
    848     bool mImgReaderInited = false;
    849     bool mPreviewInited = false;
    850 };
    851 
    852 jint throwAssertionError(JNIEnv* env, const char* message)
    853 {
    854     jclass assertionClass;
    855     const char* className = "junit/framework/AssertionFailedError";
    856 
    857     assertionClass = env->FindClass(className);
    858     if (assertionClass == nullptr) {
    859         ALOGE("Native throw error: cannot find class %s", className);
    860         return -1;
    861     }
    862     return env->ThrowNew(assertionClass, message);
    863 }
    864 
    865 extern "C" jboolean
    866 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
    867 testCameraManagerGetAndCloseNative(
    868         JNIEnv* env, jclass /*clazz*/) {
    869     bool pass = false;
    870     ALOGV("%s", __FUNCTION__);
    871     ACameraManager* cameraManager2 = nullptr;
    872     ACameraManager* cameraManager3 = nullptr;
    873     ACameraManager* cameraManager4 = nullptr;
    874     camera_status_t ret = ACAMERA_OK;
    875     ACameraManager* cameraManager = ACameraManager_create();
    876     if (cameraManager == nullptr) {
    877         LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
    878         goto cleanup;
    879     }
    880     ACameraManager_delete(cameraManager);
    881     cameraManager = nullptr;
    882 
    883     // Test get/close multiple instances
    884     cameraManager = ACameraManager_create();
    885     cameraManager2 = ACameraManager_create();
    886     if (cameraManager2 == nullptr) {
    887         LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
    888         goto cleanup;
    889     }
    890     ACameraManager_delete(cameraManager);
    891     cameraManager = nullptr;
    892     cameraManager3 = ACameraManager_create();
    893     if (cameraManager3 == nullptr) {
    894         LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
    895         goto cleanup;
    896     }
    897     cameraManager4 = ACameraManager_create();
    898         if (cameraManager4 == nullptr) {
    899         LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
    900         goto cleanup;
    901     }
    902     ACameraManager_delete(cameraManager3);
    903     ACameraManager_delete(cameraManager2);
    904     ACameraManager_delete(cameraManager4);
    905 
    906     pass = true;
    907 cleanup:
    908     if (cameraManager) {
    909         ACameraManager_delete(cameraManager);
    910     }
    911     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
    912     if (!pass) {
    913         throwAssertionError(env, errorString);
    914     }
    915     return pass;
    916 }
    917 
    918 extern "C" jboolean
    919 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
    920 testCameraManagerGetCameraIdsNative(
    921         JNIEnv* env, jclass /*clazz*/) {
    922     ALOGV("%s", __FUNCTION__);
    923     bool pass = false;
    924     ACameraManager* mgr = ACameraManager_create();
    925     ACameraIdList *cameraIdList = nullptr;
    926     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
    927     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
    928         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
    929                 ret, cameraIdList);
    930         goto cleanup;
    931     }
    932     ALOGI("Number of cameras: %d", cameraIdList->numCameras);
    933     for (int i = 0; i < cameraIdList->numCameras; i++) {
    934         ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
    935     }
    936     ACameraManager_deleteCameraIdList(cameraIdList);
    937     cameraIdList = nullptr;
    938 
    939     pass = true;
    940 cleanup:
    941     if (mgr) {
    942         ACameraManager_delete(mgr);
    943     }
    944     if (cameraIdList) {
    945         ACameraManager_deleteCameraIdList(cameraIdList);
    946     }
    947     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
    948     if (!pass) {
    949         throwAssertionError(env, errorString);
    950     }
    951     return pass;
    952 }
    953 
    954 extern "C" jboolean
    955 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
    956 testCameraManagerAvailabilityCallbackNative(
    957         JNIEnv* env, jclass /*clazz*/) {
    958     ALOGV("%s", __FUNCTION__);
    959     bool pass = false;
    960     ACameraManager* mgr = ACameraManager_create();
    961     ACameraIdList *cameraIdList = nullptr;
    962     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
    963     int numCameras = cameraIdList->numCameras;
    964     CameraServiceListener listener;
    965     ACameraManager_AvailabilityCallbacks cbs {
    966             &listener,
    967             CameraServiceListener::onAvailable,
    968             CameraServiceListener::onUnavailable};
    969     ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
    970     if (ret != ACAMERA_OK) {
    971         LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
    972         goto cleanup;
    973     }
    974     sleep(1); // sleep a second to give some time for callbacks to happen
    975 
    976     // Should at least get onAvailable for each camera once
    977     if (listener.getAvailableCount() < numCameras) {
    978         LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
    979                 numCameras, listener.getAvailableCount());
    980         goto cleanup;
    981     }
    982 
    983     ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
    984     if (ret != ACAMERA_OK) {
    985         LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
    986         goto cleanup;
    987     }
    988     pass = true;
    989 cleanup:
    990     if (cameraIdList) {
    991         ACameraManager_deleteCameraIdList(cameraIdList);
    992     }
    993     if (mgr) {
    994         ACameraManager_delete(mgr);
    995     }
    996     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
    997     if (!pass) {
    998         throwAssertionError(env, errorString);
    999     }
   1000     return pass;
   1001 }
   1002 
   1003 extern "C" jboolean
   1004 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
   1005 testCameraManagerCharacteristicsNative(
   1006         JNIEnv* env, jclass /*clazz*/) {
   1007     ALOGV("%s", __FUNCTION__);
   1008     bool pass = false;
   1009     ACameraManager* mgr = ACameraManager_create();
   1010     ACameraIdList *cameraIdList = nullptr;
   1011     ACameraMetadata* chars = nullptr;
   1012     int numCameras = 0;
   1013     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
   1014     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
   1015         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
   1016                 ret, cameraIdList);
   1017         goto cleanup;
   1018     }
   1019     numCameras = cameraIdList->numCameras;
   1020 
   1021     for (int i = 0; i < numCameras; i++) {
   1022         ret = ACameraManager_getCameraCharacteristics(
   1023                 mgr, cameraIdList->cameraIds[i], &chars);
   1024         if (ret != ACAMERA_OK) {
   1025             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
   1026             goto cleanup;
   1027         }
   1028 
   1029         int32_t numTags = 0;
   1030         const uint32_t* tags = nullptr;
   1031         ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
   1032         if (ret != ACAMERA_OK) {
   1033             LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
   1034             goto cleanup;
   1035         }
   1036 
   1037         for (int tid = 0; tid < numTags; tid++) {
   1038             uint32_t tagId = tags[tid];
   1039             ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
   1040             uint32_t sectionId = tagId >> 16;
   1041             if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
   1042                 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
   1043                 goto cleanup;
   1044             }
   1045         }
   1046 
   1047         ACameraMetadata_const_entry entry;
   1048         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
   1049         if (ret != ACAMERA_OK) {
   1050             LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
   1051             goto cleanup;
   1052         }
   1053 
   1054         // Check the entry is actually legit
   1055         if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
   1056                 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
   1057             LOG_ERROR(errorString,
   1058                     "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
   1059                     "type %d (expected %d), data %p (expected not null)",
   1060                     entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
   1061                     entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
   1062             goto cleanup;
   1063         }
   1064         // All camera supports BC except depth only cameras
   1065         bool supportBC = false, supportDepth = false;
   1066         for (uint32_t i = 0; i < entry.count; i++) {
   1067             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
   1068                 supportBC = true;
   1069             }
   1070             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
   1071                 supportDepth = true;
   1072             }
   1073         }
   1074         if (!(supportBC || supportDepth)) {
   1075             LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
   1076                     cameraIdList->cameraIds[i]);
   1077             goto cleanup;
   1078         }
   1079 
   1080         // Check get unknown value fails
   1081         uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
   1082         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_VENDOR_START, &entry);
   1083         if (ret == ACAMERA_OK) {
   1084             LOG_ERROR(errorString, "Error: get unknown tag should fail!");
   1085             goto cleanup;
   1086         }
   1087 
   1088         ACameraMetadata_free(chars);
   1089         chars = nullptr;
   1090     }
   1091 
   1092     pass = true;
   1093 cleanup:
   1094     if (chars) {
   1095         ACameraMetadata_free(chars);
   1096     }
   1097     ACameraManager_deleteCameraIdList(cameraIdList);
   1098     ACameraManager_delete(mgr);
   1099     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1100     if (!pass) {
   1101         throwAssertionError(env, errorString);
   1102     }
   1103     return pass;
   1104 }
   1105 
   1106 extern "C" jboolean
   1107 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
   1108 testCameraDeviceOpenAndCloseNative(
   1109         JNIEnv* env, jclass /*clazz*/) {
   1110     ALOGV("%s", __FUNCTION__);
   1111     int numCameras = 0;
   1112     bool pass = false;
   1113     PreviewTestCase testCase;
   1114 
   1115     camera_status_t ret = testCase.initWithErrorLog();
   1116     if (ret != ACAMERA_OK) {
   1117         // Don't log error here. testcase did it
   1118         goto cleanup;
   1119     }
   1120 
   1121     numCameras = testCase.getNumCameras();
   1122     if (numCameras < 0) {
   1123         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1124         goto cleanup;
   1125     }
   1126 
   1127     for (int i = 0; i < numCameras; i++) {
   1128         const char* cameraId = testCase.getCameraId(i);
   1129         if (cameraId == nullptr) {
   1130             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1131             goto cleanup;
   1132         }
   1133 
   1134         ret = testCase.openCamera(cameraId);
   1135         if (ret != ACAMERA_OK) {
   1136             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1137             goto cleanup;
   1138         }
   1139 
   1140         usleep(100000); // sleep to give some time for callbacks to happen
   1141 
   1142         if (testCase.isCameraAvailable(cameraId)) {
   1143             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1144             goto cleanup;
   1145         }
   1146 
   1147         ret = testCase.closeCamera();
   1148         if (ret != ACAMERA_OK) {
   1149             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
   1150             goto cleanup;
   1151         }
   1152 
   1153         usleep(100000); // sleep to give some time for callbacks to happen
   1154 
   1155         if (!testCase.isCameraAvailable(cameraId)) {
   1156             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1157             goto cleanup;
   1158         }
   1159     }
   1160 
   1161     ret = testCase.deInit();
   1162     if (ret != ACAMERA_OK) {
   1163         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1164         goto cleanup;
   1165     }
   1166 
   1167     pass = true;
   1168 cleanup:
   1169     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1170     if (!pass) {
   1171         throwAssertionError(env, errorString);
   1172     }
   1173     return pass;
   1174 }
   1175 
   1176 extern "C" jboolean
   1177 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
   1178 testCameraDeviceCreateCaptureRequestNative(
   1179         JNIEnv* env, jclass /*clazz*/) {
   1180     ALOGV("%s", __FUNCTION__);
   1181     bool pass = false;
   1182     ACameraManager* mgr = ACameraManager_create();
   1183     ACameraIdList* cameraIdList = nullptr;
   1184     ACameraDevice* device = nullptr;
   1185     ACaptureRequest* request = nullptr;
   1186     ACameraMetadata* chars = nullptr;
   1187     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
   1188 
   1189     int numCameras = cameraIdList->numCameras;
   1190     for (int i = 0; i < numCameras; i++) {
   1191         CameraDeviceListener deviceListener;
   1192         const char* cameraId = cameraIdList->cameraIds[i];
   1193         ACameraDevice_StateCallbacks deviceCb {
   1194             &deviceListener,
   1195             CameraDeviceListener::onDisconnected,
   1196             CameraDeviceListener::onError
   1197         };
   1198         ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
   1199         if (ret != ACAMERA_OK) {
   1200             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1201             goto cleanup;
   1202         }
   1203 
   1204         ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
   1205         if (ret != ACAMERA_OK || chars == nullptr) {
   1206             LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
   1207                     cameraId, ret, chars);
   1208             goto cleanup;
   1209         }
   1210         StaticInfo staticInfo(chars);
   1211 
   1212         for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
   1213             ACameraDevice_request_template templateId =
   1214                     static_cast<ACameraDevice_request_template>(t);
   1215             ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
   1216             if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
   1217                 // template not supported. skip
   1218                 continue;
   1219             }
   1220 
   1221             if (ret != ACAMERA_OK) {
   1222                 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
   1223                 goto cleanup;
   1224             }
   1225 
   1226             int32_t numTags = 0;
   1227             const uint32_t* tags = nullptr;
   1228             ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
   1229             if (ret != ACAMERA_OK) {
   1230                 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
   1231                 goto cleanup;
   1232             }
   1233 
   1234             for (int tid = 0; tid < numTags; tid++) {
   1235                 uint32_t tagId = tags[tid];
   1236                 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
   1237                 uint32_t sectionId = tagId >> 16;
   1238                 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
   1239                     LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
   1240                     goto cleanup;
   1241                 }
   1242             }
   1243 
   1244             // try get/set capture request fields
   1245             ACameraMetadata_const_entry entry;
   1246             ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
   1247             if (ret != ACAMERA_OK) {
   1248                 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
   1249                 goto cleanup;
   1250             }
   1251 
   1252             if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
   1253                     entry.count != 1) {
   1254                 LOG_ERROR(errorString,
   1255                         "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
   1256                         "count %d (expect %d)",
   1257                         entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
   1258                         entry.count, 1);
   1259                 goto cleanup;
   1260             }
   1261             if (t == TEMPLATE_MANUAL) {
   1262                 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
   1263                     LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
   1264                             entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
   1265                     goto cleanup;
   1266                 }
   1267                 // try set AE_MODE_ON
   1268                 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
   1269                 ret = ACaptureRequest_setEntry_u8(
   1270                         request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
   1271                 if (ret != ACAMERA_OK) {
   1272                     LOG_ERROR(errorString,
   1273                             "Error: Camera %s template %d: update AE mode key fail. ret %d",
   1274                             cameraId, t, ret);
   1275                     goto cleanup;
   1276                 }
   1277                 ret = ACaptureRequest_getConstEntry(
   1278                         request, ACAMERA_CONTROL_AE_MODE, &entry);
   1279                 if (ret != ACAMERA_OK) {
   1280                     LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
   1281                     goto cleanup;
   1282                 }
   1283                 if (entry.data.u8[0] != aeMode) {
   1284                     LOG_ERROR(errorString,
   1285                             "Error: AE mode key is not updated. expect %d but get %d",
   1286                             aeMode, entry.data.u8[0]);
   1287                     goto cleanup;
   1288                 }
   1289             } else {
   1290                 if (staticInfo.isColorOutputSupported()) {
   1291                     if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
   1292                         LOG_ERROR(errorString,
   1293                                 "Error: Template %d has wrong AE mode %d (expect %d)",
   1294                                 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
   1295                         goto cleanup;
   1296                     }
   1297                     // try set AE_MODE_OFF
   1298                     if (staticInfo.isCapabilitySupported(
   1299                             ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
   1300                         uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
   1301                         ret = ACaptureRequest_setEntry_u8(
   1302                                 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
   1303                         if (ret != ACAMERA_OK) {
   1304                             LOG_ERROR(errorString,
   1305                                     "Error: Camera %s template %d: update AE mode key fail. ret %d",
   1306                                     cameraId, t, ret);
   1307                             goto cleanup;
   1308                         }
   1309                         ret = ACaptureRequest_getConstEntry(
   1310                                 request, ACAMERA_CONTROL_AE_MODE, &entry);
   1311                         if (ret != ACAMERA_OK) {
   1312                             LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
   1313                             goto cleanup;
   1314                         }
   1315                         if (entry.data.u8[0] != aeMode) {
   1316                             LOG_ERROR(errorString,
   1317                                     "Error: AE mode key is not updated. expect %d but get %d",
   1318                                     aeMode, entry.data.u8[0]);
   1319                             goto cleanup;
   1320                         }
   1321                     }
   1322                 }
   1323             }
   1324             ACaptureRequest_free(request);
   1325             request = nullptr;
   1326         }
   1327 
   1328         ACameraMetadata_free(chars);
   1329         chars = nullptr;
   1330         ACameraDevice_close(device);
   1331         device = nullptr;
   1332     }
   1333 
   1334     pass = true;
   1335 cleanup:
   1336     if (cameraIdList) {
   1337         ACameraManager_deleteCameraIdList(cameraIdList);
   1338     }
   1339     if (request) {
   1340         ACaptureRequest_free(request);
   1341     }
   1342     if (chars) {
   1343         ACameraMetadata_free(chars);
   1344     }
   1345     if (device) {
   1346         ACameraDevice_close(device);
   1347     }
   1348     if (mgr) {
   1349         ACameraManager_delete(mgr);
   1350     }
   1351     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1352     if (!pass) {
   1353         throwAssertionError(env, errorString);
   1354     }
   1355     return pass;
   1356 }
   1357 
   1358 extern "C" jboolean
   1359 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
   1360 testCameraDeviceSessionOpenAndCloseNative(
   1361         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
   1362     ALOGV("%s", __FUNCTION__);
   1363     int numCameras = 0;
   1364     bool pass = false;
   1365     PreviewTestCase testCase;
   1366 
   1367     camera_status_t ret = testCase.initWithErrorLog();
   1368     if (ret != ACAMERA_OK) {
   1369         // Don't log error here. testcase did it
   1370         goto cleanup;
   1371     }
   1372 
   1373     numCameras = testCase.getNumCameras();
   1374     if (numCameras < 0) {
   1375         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1376         goto cleanup;
   1377     }
   1378 
   1379     for (int i = 0; i < numCameras; i++) {
   1380         const char* cameraId = testCase.getCameraId(i);
   1381         if (cameraId == nullptr) {
   1382             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1383             goto cleanup;
   1384         }
   1385 
   1386         ret = testCase.openCamera(cameraId);
   1387         if (ret != ACAMERA_OK) {
   1388             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1389             goto cleanup;
   1390         }
   1391 
   1392         usleep(100000); // sleep to give some time for callbacks to happen
   1393 
   1394         if (testCase.isCameraAvailable(cameraId)) {
   1395             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1396             goto cleanup;
   1397         }
   1398 
   1399         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
   1400         if (previewAnw == nullptr) {
   1401             LOG_ERROR(errorString, "Null ANW from preview surface!");
   1402             goto cleanup;
   1403         }
   1404 
   1405         CaptureSessionListener* sessionListener = testCase.getSessionListener();
   1406         if (sessionListener == nullptr) {
   1407             LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
   1408             goto cleanup;
   1409         }
   1410 
   1411         // Try open/close session multiple times
   1412         for (int j = 0; j < 5; j++) {
   1413             ret = testCase.createCaptureSessionWithLog();
   1414             if (ret != ACAMERA_OK) {
   1415                 // Don't log error here. testcase did it
   1416                 goto cleanup;
   1417             }
   1418 
   1419             usleep(100000); // sleep to give some time for callbacks to happen
   1420 
   1421             if (!sessionListener->isIdle()) {
   1422                 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
   1423                         cameraId);
   1424                 goto cleanup;
   1425             }
   1426 
   1427             testCase.closeSession();
   1428 
   1429             usleep(100000); // sleep to give some time for callbacks to happen
   1430             if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
   1431                 LOG_ERROR(errorString,
   1432                         "Session for camera %s close error. isClosde %d close count %d",
   1433                         cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
   1434                 goto cleanup;
   1435             }
   1436             sessionListener->reset();
   1437         }
   1438 
   1439         // Try open/close really fast
   1440         ret = testCase.createCaptureSessionWithLog();
   1441         if (ret != ACAMERA_OK) {
   1442             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
   1443                     cameraId, ret);
   1444             goto cleanup;
   1445         }
   1446         testCase.closeSession();
   1447         usleep(100000); // sleep to give some time for callbacks to happen
   1448         if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
   1449             LOG_ERROR(errorString,
   1450                     "Session for camera %s close error. isClosde %d close count %d",
   1451                     cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
   1452             goto cleanup;
   1453         }
   1454 
   1455         ret = testCase.resetWithErrorLog();
   1456         if (ret != ACAMERA_OK) {
   1457             // Don't log error here. testcase did it
   1458             goto cleanup;
   1459         }
   1460 
   1461         usleep(100000); // sleep to give some time for callbacks to happen
   1462 
   1463         if (!testCase.isCameraAvailable(cameraId)) {
   1464             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1465             goto cleanup;
   1466         }
   1467     }
   1468 
   1469     ret = testCase.deInit();
   1470     if (ret != ACAMERA_OK) {
   1471         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1472         goto cleanup;
   1473     }
   1474 
   1475     pass = true;
   1476 cleanup:
   1477     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1478     if (!pass) {
   1479         throwAssertionError(env, errorString);
   1480     }
   1481     return pass;
   1482 }
   1483 
   1484 extern "C" jboolean
   1485 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
   1486 testCameraDeviceSimplePreviewNative(
   1487         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
   1488     ALOGV("%s", __FUNCTION__);
   1489     int numCameras = 0;
   1490     bool pass = false;
   1491     PreviewTestCase testCase;
   1492 
   1493     camera_status_t ret = testCase.initWithErrorLog();
   1494     if (ret != ACAMERA_OK) {
   1495         // Don't log error here. testcase did it
   1496         goto cleanup;
   1497     }
   1498 
   1499     numCameras = testCase.getNumCameras();
   1500     if (numCameras < 0) {
   1501         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1502         goto cleanup;
   1503     }
   1504 
   1505     for (int i = 0; i < numCameras; i++) {
   1506         const char* cameraId = testCase.getCameraId(i);
   1507         if (cameraId == nullptr) {
   1508             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1509             goto cleanup;
   1510         }
   1511 
   1512         ret = testCase.openCamera(cameraId);
   1513         if (ret != ACAMERA_OK) {
   1514             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1515             goto cleanup;
   1516         }
   1517 
   1518         usleep(100000); // sleep to give some time for callbacks to happen
   1519 
   1520         if (testCase.isCameraAvailable(cameraId)) {
   1521             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1522             goto cleanup;
   1523         }
   1524 
   1525         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
   1526         if (previewAnw == nullptr) {
   1527             LOG_ERROR(errorString, "Null ANW from preview surface!");
   1528             goto cleanup;
   1529         }
   1530 
   1531         ret = testCase.createCaptureSessionWithLog();
   1532         if (ret != ACAMERA_OK) {
   1533             // Don't log error here. testcase did it
   1534             goto cleanup;
   1535         }
   1536 
   1537         ret = testCase.createRequestsWithErrorLog();
   1538         if (ret != ACAMERA_OK) {
   1539             // Don't log error here. testcase did it
   1540             goto cleanup;
   1541         }
   1542 
   1543         ret = testCase.startPreview();
   1544         if (ret != ACAMERA_OK) {
   1545             LOG_ERROR(errorString, "Start preview failed!");
   1546             goto cleanup;
   1547         }
   1548 
   1549         sleep(3);
   1550 
   1551         ret = testCase.resetWithErrorLog();
   1552         if (ret != ACAMERA_OK) {
   1553             // Don't log error here. testcase did it
   1554             goto cleanup;
   1555         }
   1556 
   1557         usleep(100000); // sleep to give some time for callbacks to happen
   1558 
   1559         if (!testCase.isCameraAvailable(cameraId)) {
   1560             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1561             goto cleanup;
   1562         }
   1563     }
   1564 
   1565     ret = testCase.deInit();
   1566     if (ret != ACAMERA_OK) {
   1567         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1568         goto cleanup;
   1569     }
   1570 
   1571     pass = true;
   1572 cleanup:
   1573     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1574     if (!pass) {
   1575         throwAssertionError(env, errorString);
   1576     }
   1577     return pass;
   1578 }
   1579 
   1580 extern "C" jboolean
   1581 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
   1582 testJpegNative(
   1583         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
   1584     ALOGV("%s", __FUNCTION__);
   1585     const int NUM_TEST_IMAGES = 10;
   1586     const int TEST_WIDTH  = 640;
   1587     const int TEST_HEIGHT = 480;
   1588     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
   1589     int numCameras = 0;
   1590     bool pass = false;
   1591     PreviewTestCase testCase;
   1592 
   1593     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
   1594     testCase.setDumpFilePathBase(outPath);
   1595     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
   1596 
   1597     camera_status_t ret = testCase.initWithErrorLog();
   1598     if (ret != ACAMERA_OK) {
   1599         // Don't log error here. testcase did it
   1600         goto cleanup;
   1601     }
   1602 
   1603     numCameras = testCase.getNumCameras();
   1604     if (numCameras < 0) {
   1605         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1606         goto cleanup;
   1607     }
   1608 
   1609     for (int i = 0; i < numCameras; i++) {
   1610         const char* cameraId = testCase.getCameraId(i);
   1611         if (cameraId == nullptr) {
   1612             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1613             goto cleanup;
   1614         }
   1615 
   1616         ret = testCase.openCamera(cameraId);
   1617         if (ret != ACAMERA_OK) {
   1618             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1619             goto cleanup;
   1620         }
   1621 
   1622         usleep(100000); // sleep to give some time for callbacks to happen
   1623 
   1624         if (testCase.isCameraAvailable(cameraId)) {
   1625             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1626             goto cleanup;
   1627         }
   1628 
   1629         mediaRet = testCase.initImageReaderWithErrorLog(
   1630                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES);
   1631         if (mediaRet != AMEDIA_OK) {
   1632             // Don't log error here. testcase did it
   1633             goto cleanup;
   1634         }
   1635 
   1636         ret = testCase.createCaptureSessionWithLog();
   1637         if (ret != ACAMERA_OK) {
   1638             // Don't log error here. testcase did it
   1639             goto cleanup;
   1640         }
   1641 
   1642         ret = testCase.createRequestsWithErrorLog();
   1643         if (ret != ACAMERA_OK) {
   1644             // Don't log error here. testcase did it
   1645             goto cleanup;
   1646         }
   1647 
   1648         // Do some still capture
   1649         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
   1650             ret = testCase.takePicture();
   1651             if (ret != ACAMERA_OK) {
   1652                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
   1653                         cameraId, capture, ret);
   1654                 goto cleanup;
   1655             }
   1656         }
   1657 
   1658         // wait until all capture finished
   1659         for (int i = 0; i < 50; i++) {
   1660             usleep(100000); // sleep 100ms
   1661             if (testCase.getReaderImageCount() == NUM_TEST_IMAGES) {
   1662                 ALOGI("Session take ~%d ms to capture %d images",
   1663                         i*100, NUM_TEST_IMAGES);
   1664                 break;
   1665             }
   1666         }
   1667 
   1668         if (testCase.getReaderImageCount() != NUM_TEST_IMAGES) {
   1669             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
   1670                     cameraId, NUM_TEST_IMAGES, testCase.getReaderImageCount());
   1671             goto cleanup;
   1672         }
   1673 
   1674         ret = testCase.resetWithErrorLog();
   1675         if (ret != ACAMERA_OK) {
   1676             // Don't log error here. testcase did it
   1677             goto cleanup;
   1678         }
   1679 
   1680         usleep(100000); // sleep to give some time for callbacks to happen
   1681 
   1682         if (!testCase.isCameraAvailable(cameraId)) {
   1683             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1684             goto cleanup;
   1685         }
   1686     }
   1687 
   1688     ret = testCase.deInit();
   1689     if (ret != ACAMERA_OK) {
   1690         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1691         goto cleanup;
   1692     }
   1693 
   1694     pass = true;
   1695 
   1696 cleanup:
   1697     env->ReleaseStringUTFChars(jOutPath, outPath);
   1698     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1699     if (!pass) {
   1700         throwAssertionError(env, errorString);
   1701     }
   1702     return pass;
   1703 }
   1704 
   1705 
   1706 extern "C" jboolean
   1707 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
   1708 testStillCaptureNative(
   1709         JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
   1710     ALOGV("%s", __FUNCTION__);
   1711     const int NUM_TEST_IMAGES = 10;
   1712     const int TEST_WIDTH  = 640;
   1713     const int TEST_HEIGHT = 480;
   1714     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
   1715     int numCameras = 0;
   1716     bool pass = false;
   1717     PreviewTestCase testCase;
   1718 
   1719     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
   1720     testCase.setDumpFilePathBase(outPath);
   1721     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
   1722 
   1723     camera_status_t ret = testCase.initWithErrorLog();
   1724     if (ret != ACAMERA_OK) {
   1725         // Don't log error here. testcase did it
   1726         goto cleanup;
   1727     }
   1728 
   1729     numCameras = testCase.getNumCameras();
   1730     if (numCameras < 0) {
   1731         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1732         goto cleanup;
   1733     }
   1734 
   1735     for (int i = 0; i < numCameras; i++) {
   1736         const char* cameraId = testCase.getCameraId(i);
   1737         if (cameraId == nullptr) {
   1738             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1739             goto cleanup;
   1740         }
   1741 
   1742         ret = testCase.openCamera(cameraId);
   1743         if (ret != ACAMERA_OK) {
   1744             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1745             goto cleanup;
   1746         }
   1747 
   1748         usleep(100000); // sleep to give some time for callbacks to happen
   1749 
   1750         if (testCase.isCameraAvailable(cameraId)) {
   1751             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1752             goto cleanup;
   1753         }
   1754 
   1755         mediaRet = testCase.initImageReaderWithErrorLog(
   1756                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES);
   1757         if (mediaRet != AMEDIA_OK) {
   1758             // Don't log error here. testcase did it
   1759             goto cleanup;
   1760         }
   1761 
   1762         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
   1763         if (previewAnw == nullptr) {
   1764             LOG_ERROR(errorString, "Null ANW from preview surface!");
   1765             goto cleanup;
   1766         }
   1767 
   1768         ret = testCase.createCaptureSessionWithLog();
   1769         if (ret != ACAMERA_OK) {
   1770             // Don't log error here. testcase did it
   1771             goto cleanup;
   1772         }
   1773 
   1774         ret = testCase.createRequestsWithErrorLog();
   1775         if (ret != ACAMERA_OK) {
   1776             // Don't log error here. testcase did it
   1777             goto cleanup;
   1778         }
   1779 
   1780         ret = testCase.startPreview();
   1781         if (ret != ACAMERA_OK) {
   1782             LOG_ERROR(errorString, "Start preview failed!");
   1783             goto cleanup;
   1784         }
   1785 
   1786         // Let preview run some time
   1787         sleep(3);
   1788 
   1789         // Do some still capture
   1790         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
   1791             ret = testCase.takePicture();
   1792             if (ret != ACAMERA_OK) {
   1793                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
   1794                         cameraId, capture, ret);
   1795                 goto cleanup;
   1796             }
   1797         }
   1798 
   1799         // wait until all capture finished
   1800         for (int i = 0; i < 50; i++) {
   1801             usleep(100000); // sleep 100ms
   1802             if (testCase.getReaderImageCount() == NUM_TEST_IMAGES) {
   1803                 ALOGI("Session take ~%d ms to capture %d images",
   1804                         i*100, NUM_TEST_IMAGES);
   1805                 break;
   1806             }
   1807         }
   1808 
   1809         if (testCase.getReaderImageCount() != NUM_TEST_IMAGES) {
   1810             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
   1811                     cameraId, NUM_TEST_IMAGES, testCase.getReaderImageCount());
   1812             goto cleanup;
   1813         }
   1814 
   1815         ret = testCase.resetWithErrorLog();
   1816         if (ret != ACAMERA_OK) {
   1817             // Don't log error here. testcase did it
   1818             goto cleanup;
   1819         }
   1820 
   1821         usleep(100000); // sleep to give some time for callbacks to happen
   1822 
   1823         if (!testCase.isCameraAvailable(cameraId)) {
   1824             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1825             goto cleanup;
   1826         }
   1827     }
   1828 
   1829     ret = testCase.deInit();
   1830     if (ret != ACAMERA_OK) {
   1831         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1832         goto cleanup;
   1833     }
   1834 
   1835     pass = true;
   1836 cleanup:
   1837     env->ReleaseStringUTFChars(jOutPath, outPath);
   1838     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1839     if (!pass) {
   1840         throwAssertionError(env, errorString);
   1841     }
   1842     return pass;
   1843 }
   1844 
   1845