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 "camera/NdkCameraError.h"
     33 #include "camera/NdkCameraManager.h"
     34 #include "camera/NdkCameraDevice.h"
     35 #include "camera/NdkCameraCaptureSession.h"
     36 #include "media/NdkImage.h"
     37 #include "media/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 
    242 class ImageReaderListener {
    243   public:
    244     // count, acquire, validate, and delete AImage when a new image is available
    245     static void validateImageCb(void* obj, AImageReader* reader) {
    246         ALOGV("%s", __FUNCTION__);
    247         if (obj == nullptr) {
    248             return;
    249         }
    250         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
    251         std::lock_guard<std::mutex> lock(thiz->mMutex);
    252         thiz->mOnImageAvailableCount++;
    253 
    254         AImage* img = nullptr;
    255         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
    256         if (ret != AMEDIA_OK || img == nullptr) {
    257             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
    258                     __FUNCTION__, reader, ret, img);
    259             return;
    260         }
    261 
    262         // TODO: validate image content
    263         int32_t format = -1;
    264         ret = AImage_getFormat(img, &format);
    265         if (ret != AMEDIA_OK || format == -1) {
    266             ALOGE("%s: get format for image %p failed! ret: %d, format %d",
    267                     __FUNCTION__, img, ret, format);
    268         }
    269 
    270         // Save jpeg to SD card
    271         if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
    272             int32_t numPlanes = 0;
    273             ret = AImage_getNumberOfPlanes(img, &numPlanes);
    274             if (ret != AMEDIA_OK || numPlanes != 1) {
    275                 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
    276                         __FUNCTION__, img, ret, numPlanes);
    277                 AImage_delete(img);
    278                 return;
    279             }
    280 
    281             int32_t width = -1, height = -1;
    282             ret = AImage_getWidth(img, &width);
    283             if (ret != AMEDIA_OK || width <= 0) {
    284                 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
    285                         __FUNCTION__, img, ret, width);
    286                 AImage_delete(img);
    287                 return;
    288             }
    289 
    290             ret = AImage_getHeight(img, &height);
    291             if (ret != AMEDIA_OK || height <= 0) {
    292                 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
    293                         __FUNCTION__, img, ret, height);
    294                 AImage_delete(img);
    295                 return;
    296             }
    297 
    298             uint8_t* data = nullptr;
    299             int dataLength = 0;
    300             ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
    301             if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
    302                 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
    303                         __FUNCTION__, img, ret, data, dataLength);
    304                 AImage_delete(img);
    305                 return;
    306             }
    307 
    308 #if 0
    309             char dumpFilePath[512];
    310             sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
    311             ALOGI("Writing jpeg file to %s", dumpFilePath);
    312             FILE* file = fopen(dumpFilePath,"w+");
    313 
    314             if (file != nullptr) {
    315                 fwrite(data, 1, dataLength, file);
    316                 fflush(file);
    317                 fclose(file);
    318             }
    319 #endif
    320         }
    321 
    322         AImage_delete(img);
    323     }
    324 
    325     // count, acquire image but not delete the image
    326     static void acquireImageCb(void* obj, AImageReader* reader) {
    327         ALOGV("%s", __FUNCTION__);
    328         if (obj == nullptr) {
    329             return;
    330         }
    331         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
    332         std::lock_guard<std::mutex> lock(thiz->mMutex);
    333         thiz->mOnImageAvailableCount++;
    334 
    335         // Acquire, but not closing.
    336         AImage* img = nullptr;
    337         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
    338         if (ret != AMEDIA_OK || img == nullptr) {
    339             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
    340                     __FUNCTION__, reader, ret, img);
    341             return;
    342         }
    343         return;
    344     }
    345 
    346     int onImageAvailableCount() {
    347         std::lock_guard<std::mutex> lock(mMutex);
    348         return mOnImageAvailableCount;
    349     }
    350 
    351     void setDumpFilePathBase(const char* path) {
    352         std::lock_guard<std::mutex> lock(mMutex);
    353         mDumpFilePathBase = path;
    354     }
    355 
    356   private:
    357     // TODO: add mReader to make sure each listener is associated to one reader?
    358     std::mutex mMutex;
    359     int mOnImageAvailableCount = 0;
    360     const char* mDumpFilePathBase = nullptr;
    361 };
    362 
    363 class StaticInfo {
    364   public:
    365     explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
    366 
    367     bool isColorOutputSupported() {
    368         return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
    369     }
    370 
    371     bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
    372         ACameraMetadata_const_entry entry;
    373         ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
    374         for (uint32_t i = 0; i < entry.count; i++) {
    375             if (entry.data.u8[i] == cap) {
    376                 return true;
    377             }
    378         }
    379         return false;
    380     }
    381   private:
    382     const ACameraMetadata* mChars;
    383 };
    384 
    385 class PreviewTestCase {
    386   public:
    387     ~PreviewTestCase() {
    388         resetCamera();
    389         deInit();
    390         if (mCameraManager) {
    391             ACameraManager_delete(mCameraManager);
    392             mCameraManager = nullptr;
    393         }
    394     }
    395 
    396     PreviewTestCase() {
    397         // create is guaranteed to succeed;
    398         createManager();
    399     }
    400 
    401     // Free all resources except camera manager
    402     void resetCamera() {
    403         mSessionListener.reset();
    404         if (mSession) {
    405             ACameraCaptureSession_close(mSession);
    406             mSession = nullptr;
    407         }
    408         if (mDevice) {
    409             ACameraDevice_close(mDevice);
    410             mDevice = nullptr;
    411         }
    412         if (mImgReader) {
    413             AImageReader_delete(mImgReader);
    414             // No need to call ANativeWindow_release on imageReaderAnw
    415             mImgReaderAnw = nullptr;
    416             mImgReader = nullptr;
    417         }
    418         if (mPreviewAnw) {
    419             ANativeWindow_release(mPreviewAnw);
    420             mPreviewAnw = nullptr;
    421         }
    422         if (mOutputs) {
    423             ACaptureSessionOutputContainer_free(mOutputs);
    424             mOutputs = nullptr;
    425         }
    426         if (mPreviewOutput) {
    427             ACaptureSessionOutput_free(mPreviewOutput);
    428             mPreviewOutput = nullptr;
    429         }
    430         if (mImgReaderOutput) {
    431             ACaptureSessionOutput_free(mImgReaderOutput);
    432             mImgReaderOutput = nullptr;
    433         }
    434         if (mPreviewRequest) {
    435             ACaptureRequest_free(mPreviewRequest);
    436             mPreviewRequest = nullptr;
    437         }
    438         if (mStillRequest) {
    439             ACaptureRequest_free(mStillRequest);
    440             mStillRequest = nullptr;
    441         }
    442         if (mReqPreviewOutput) {
    443             ACameraOutputTarget_free(mReqPreviewOutput);
    444             mReqPreviewOutput = nullptr;
    445         }
    446         if (mReqImgReaderOutput) {
    447             ACameraOutputTarget_free(mReqImgReaderOutput);
    448             mReqImgReaderOutput = nullptr;
    449         }
    450 
    451         mImgReaderInited = false;
    452         mPreviewInited = false;
    453     }
    454 
    455     camera_status_t initWithErrorLog() {
    456         camera_status_t ret = ACameraManager_getCameraIdList(
    457                 mCameraManager, &mCameraIdList);
    458         if (ret != ACAMERA_OK) {
    459             LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
    460             return ret;
    461         }
    462         ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
    463         if (ret != ACAMERA_OK) {
    464             LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
    465             return ret;
    466         }
    467         mMgrInited = true;
    468         return ACAMERA_OK;
    469     }
    470 
    471     camera_status_t deInit () {
    472         if (!mMgrInited) {
    473             return ACAMERA_OK;
    474         }
    475 
    476         camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
    477                 mCameraManager, &mServiceCb);
    478         if (ret != ACAMERA_OK) {
    479             ALOGE("Unregister availability callback failed: ret %d", ret);
    480             return ret;
    481         }
    482 
    483         if (mCameraIdList) {
    484             ACameraManager_deleteCameraIdList(mCameraIdList);
    485             mCameraIdList = nullptr;
    486         }
    487         mMgrInited = false;
    488         return ACAMERA_OK;
    489     }
    490 
    491     int getNumCameras() {
    492         if (!mMgrInited || !mCameraIdList) {
    493             return -1;
    494         }
    495         return mCameraIdList->numCameras;
    496     }
    497 
    498     const char* getCameraId(int idx) {
    499         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
    500             return nullptr;
    501         }
    502         return mCameraIdList->cameraIds[idx];
    503     }
    504 
    505     camera_status_t openCamera(const char* cameraId) {
    506         if (mDevice) {
    507             ALOGE("Cannot open camera before closing previously open one");
    508             return ACAMERA_ERROR_INVALID_PARAMETER;
    509         }
    510         mCameraId = cameraId;
    511         return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
    512     }
    513 
    514     camera_status_t closeCamera() {
    515         camera_status_t ret = ACameraDevice_close(mDevice);
    516         mDevice = nullptr;
    517         return ret;
    518     }
    519 
    520     bool isCameraAvailable(const char* cameraId) {
    521         if (!mMgrInited) {
    522             ALOGE("Camera service listener has not been registered!");
    523         }
    524         return mServiceListener.isAvailable(cameraId);
    525     }
    526 
    527     media_status_t initImageReaderWithErrorLog(
    528             int32_t width, int32_t height, int32_t format, int32_t maxImages,
    529             AImageReader_ImageListener* listener) {
    530         if (mImgReader || mImgReaderAnw) {
    531             LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
    532             return AMEDIA_ERROR_UNKNOWN;
    533         }
    534 
    535         media_status_t ret = AImageReader_new(
    536                 width, height, format,
    537                 maxImages, &mImgReader);
    538         if (ret != AMEDIA_OK) {
    539             LOG_ERROR(errorString, "Create image reader. ret %d", ret);
    540             return ret;
    541         }
    542         if (mImgReader == nullptr) {
    543             LOG_ERROR(errorString, "null image reader created");
    544             return AMEDIA_ERROR_UNKNOWN;
    545         }
    546 
    547         ret = AImageReader_setImageListener(mImgReader, listener);
    548         if (ret != AMEDIA_OK) {
    549             LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
    550             return ret;
    551         }
    552 
    553         ret = AImageReader_getWindow(mImgReader, &mImgReaderAnw);
    554         if (ret != AMEDIA_OK) {
    555             LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
    556             return ret;
    557         }
    558         if (mImgReaderAnw == nullptr) {
    559             LOG_ERROR(errorString, "Null ANW from AImageReader!");
    560             return AMEDIA_ERROR_UNKNOWN;
    561         }
    562         mImgReaderInited = true;
    563         return AMEDIA_OK;
    564     }
    565 
    566     ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
    567         if (mPreviewAnw) {
    568             ALOGE("Cannot init preview twice!");
    569             return nullptr;
    570         }
    571         mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
    572         mPreviewInited = true;
    573         return mPreviewAnw;
    574     }
    575 
    576     camera_status_t createCaptureSessionWithLog() {
    577         if (mSession) {
    578             LOG_ERROR(errorString, "Cannot create session before closing existing one");
    579             return ACAMERA_ERROR_UNKNOWN;
    580         }
    581 
    582         if (!mMgrInited || (!mImgReaderInited && !mPreviewInited)) {
    583             LOG_ERROR(errorString, "Cannot create session. mgrInit %d readerInit %d previewInit %d",
    584                     mMgrInited, mImgReaderInited, mPreviewInited);
    585             return ACAMERA_ERROR_UNKNOWN;
    586         }
    587 
    588         camera_status_t ret = ACaptureSessionOutputContainer_create(&mOutputs);
    589         if (ret != ACAMERA_OK) {
    590             LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
    591             return ret;
    592         }
    593 
    594         if (mImgReaderInited) {
    595             ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
    596             if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
    597                 LOG_ERROR(errorString,
    598                         "Sesssion image reader output create fail! ret %d output %p",
    599                         ret, mImgReaderOutput);
    600                 if (ret == ACAMERA_OK) {
    601                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
    602                 }
    603                 return ret;
    604             }
    605 
    606             ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
    607             if (ret != ACAMERA_OK) {
    608                 LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
    609                 return ret;
    610             }
    611         }
    612 
    613         if (mPreviewInited) {
    614             ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
    615             if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
    616                 LOG_ERROR(errorString,
    617                         "Sesssion preview output create fail! ret %d output %p",
    618                         ret, mPreviewOutput);
    619                 if (ret == ACAMERA_OK) {
    620                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
    621                 }
    622                 return ret;
    623             }
    624 
    625             ret = ACaptureSessionOutputContainer_add(mOutputs, mPreviewOutput);
    626             if (ret != ACAMERA_OK) {
    627                 LOG_ERROR(errorString, "Sesssion preview output add failed! ret %d", ret);
    628                 return ret;
    629             }
    630         }
    631 
    632         ret = ACameraDevice_createCaptureSession(
    633                 mDevice, mOutputs, &mSessionCb, &mSession);
    634         if (ret != ACAMERA_OK || mSession == nullptr) {
    635             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
    636                     mCameraId, ret, mSession);
    637             if (ret == ACAMERA_OK) {
    638                 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
    639             }
    640             return ret;
    641         }
    642 
    643         return ACAMERA_OK;
    644     }
    645 
    646     void closeSession() {
    647         if (mSession != nullptr) {
    648             ACameraCaptureSession_close(mSession);
    649         }
    650         if (mOutputs) {
    651             ACaptureSessionOutputContainer_free(mOutputs);
    652             mOutputs = nullptr;
    653         }
    654         if (mPreviewOutput) {
    655             ACaptureSessionOutput_free(mPreviewOutput);
    656             mPreviewOutput = nullptr;
    657         }
    658         if (mImgReaderOutput) {
    659             ACaptureSessionOutput_free(mImgReaderOutput);
    660             mImgReaderOutput = nullptr;
    661         }
    662         mSession = nullptr;
    663     }
    664 
    665     camera_status_t createRequestsWithErrorLog() {
    666         if (mPreviewRequest || mStillRequest) {
    667             LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
    668             return ACAMERA_ERROR_UNKNOWN;
    669         }
    670 
    671         if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
    672             LOG_ERROR(errorString,
    673                     "Cannot create request. device %p previewInit %d readeInit %d",
    674                     mDevice, mPreviewInited, mImgReaderInited);
    675             return ACAMERA_ERROR_UNKNOWN;
    676         }
    677 
    678         camera_status_t ret;
    679         if (mPreviewInited) {
    680             ret = ACameraDevice_createCaptureRequest(
    681                     mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
    682             if (ret != ACAMERA_OK) {
    683                 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
    684                         mCameraId, ret);
    685                 return ret;
    686             }
    687 
    688             ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
    689             if (ret != ACAMERA_OK) {
    690                 LOG_ERROR(errorString,
    691                         "Camera %s create request preview output target failed. ret %d",
    692                         mCameraId, ret);
    693                 return ret;
    694             }
    695 
    696             ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
    697             if (ret != ACAMERA_OK) {
    698                 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
    699                         mCameraId, ret);
    700                 return ret;
    701             }
    702         } else {
    703             ALOGI("Preview not inited. Will not create preview request!");
    704         }
    705 
    706         if (mImgReaderInited) {
    707             ret = ACameraDevice_createCaptureRequest(
    708                     mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
    709             if (ret != ACAMERA_OK) {
    710                 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
    711                         mCameraId, ret);
    712                 return ret;
    713             }
    714 
    715             ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
    716             if (ret != ACAMERA_OK) {
    717                 LOG_ERROR(errorString,
    718                         "Camera %s create request reader output target failed. ret %d",
    719                         mCameraId, ret);
    720                 return ret;
    721             }
    722 
    723             ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
    724             if (ret != ACAMERA_OK) {
    725                 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
    726                         mCameraId, ret);
    727                 return ret;
    728             }
    729 
    730             if (mPreviewInited) {
    731                 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
    732                 if (ret != ACAMERA_OK) {
    733                     LOG_ERROR(errorString,
    734                             "Camera %s add still request preview output failed. ret %d",
    735                             mCameraId, ret);
    736                     return ret;
    737                 }
    738             }
    739         } else {
    740             ALOGI("AImageReader not inited. Will not create still request!");
    741         }
    742 
    743         return ACAMERA_OK;
    744     }
    745 
    746     camera_status_t startPreview() {
    747         if (mSession == nullptr || mPreviewRequest == nullptr) {
    748             ALOGE("Testcase cannot start preview: session %p, preview request %p",
    749                     mSession, mPreviewRequest);
    750             return ACAMERA_ERROR_UNKNOWN;
    751         }
    752         int previewSeqId;
    753         return ACameraCaptureSession_setRepeatingRequest(
    754                 mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
    755     }
    756 
    757     camera_status_t takePicture() {
    758         if (mSession == nullptr || mStillRequest == nullptr) {
    759             ALOGE("Testcase cannot take picture: session %p, still request %p",
    760                     mSession, mStillRequest);
    761             return ACAMERA_ERROR_UNKNOWN;
    762         }
    763         int seqId;
    764         return ACameraCaptureSession_capture(
    765                 mSession, nullptr, 1, &mStillRequest, &seqId);
    766     }
    767 
    768     camera_status_t resetWithErrorLog() {
    769         camera_status_t ret;
    770 
    771         closeSession();
    772 
    773         for (int i = 0; i < 50; i++) {
    774             usleep(100000); // sleep 100ms
    775             if (mSessionListener.isClosed()) {
    776                 ALOGI("Session take ~%d ms to close", i*100);
    777                 break;
    778             }
    779         }
    780 
    781         if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
    782             LOG_ERROR(errorString,
    783                     "Session for camera %s close error. isClosde %d close count %d",
    784                     mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
    785             return ACAMERA_ERROR_UNKNOWN;
    786         }
    787         mSessionListener.reset();
    788 
    789         ret = closeCamera();
    790         if (ret != ACAMERA_OK) {
    791             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
    792             return ret;
    793         }
    794 
    795         resetCamera();
    796         return ACAMERA_OK;
    797     }
    798 
    799     CaptureSessionListener* getSessionListener() {
    800         return &mSessionListener;
    801     }
    802 
    803   private:
    804     ACameraManager* createManager() {
    805         if (!mCameraManager) {
    806             mCameraManager = ACameraManager_create();
    807         }
    808         return mCameraManager;
    809     }
    810 
    811     CameraServiceListener mServiceListener;
    812     ACameraManager_AvailabilityCallbacks mServiceCb {
    813         &mServiceListener,
    814         CameraServiceListener::onAvailable,
    815         CameraServiceListener::onUnavailable
    816     };
    817     CameraDeviceListener mDeviceListener;
    818     ACameraDevice_StateCallbacks mDeviceCb {
    819         &mDeviceListener,
    820         CameraDeviceListener::onDisconnected,
    821         CameraDeviceListener::onError
    822     };
    823     CaptureSessionListener mSessionListener;
    824     ACameraCaptureSession_stateCallbacks mSessionCb {
    825         &mSessionListener,
    826         CaptureSessionListener::onClosed,
    827         CaptureSessionListener::onReady,
    828         CaptureSessionListener::onActive
    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, badTag, &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 bool nativeImageReaderTestBase(
   1581         JNIEnv* env, jstring jOutPath, AImageReader_ImageCallback cb) {
   1582     const int NUM_TEST_IMAGES = 10;
   1583     const int TEST_WIDTH  = 640;
   1584     const int TEST_HEIGHT = 480;
   1585     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
   1586     int numCameras = 0;
   1587     bool pass = false;
   1588     PreviewTestCase testCase;
   1589 
   1590     const char* outPath = (jOutPath == nullptr) ? nullptr :
   1591             env->GetStringUTFChars(jOutPath, nullptr);
   1592     if (outPath != nullptr) {
   1593         ALOGI("%s: out path is %s", __FUNCTION__, outPath);
   1594     }
   1595 
   1596     camera_status_t ret = testCase.initWithErrorLog();
   1597     if (ret != ACAMERA_OK) {
   1598         // Don't log error here. testcase did it
   1599         goto cleanup;
   1600     }
   1601 
   1602     numCameras = testCase.getNumCameras();
   1603     if (numCameras < 0) {
   1604         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1605         goto cleanup;
   1606     }
   1607 
   1608     for (int i = 0; i < numCameras; i++) {
   1609         const char* cameraId = testCase.getCameraId(i);
   1610         if (cameraId == nullptr) {
   1611             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1612             goto cleanup;
   1613         }
   1614 
   1615         ret = testCase.openCamera(cameraId);
   1616         if (ret != ACAMERA_OK) {
   1617             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1618             goto cleanup;
   1619         }
   1620 
   1621         usleep(100000); // sleep to give some time for callbacks to happen
   1622 
   1623         if (testCase.isCameraAvailable(cameraId)) {
   1624             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1625             goto cleanup;
   1626         }
   1627 
   1628         ImageReaderListener readerListener;
   1629         AImageReader_ImageListener readerCb { &readerListener, cb };
   1630         readerListener.setDumpFilePathBase(outPath);
   1631 
   1632         mediaRet = testCase.initImageReaderWithErrorLog(
   1633                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
   1634                 &readerCb);
   1635         if (mediaRet != AMEDIA_OK) {
   1636             // Don't log error here. testcase did it
   1637             goto cleanup;
   1638         }
   1639 
   1640         ret = testCase.createCaptureSessionWithLog();
   1641         if (ret != ACAMERA_OK) {
   1642             // Don't log error here. testcase did it
   1643             goto cleanup;
   1644         }
   1645 
   1646         ret = testCase.createRequestsWithErrorLog();
   1647         if (ret != ACAMERA_OK) {
   1648             // Don't log error here. testcase did it
   1649             goto cleanup;
   1650         }
   1651 
   1652         // Do some still capture
   1653         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
   1654             ret = testCase.takePicture();
   1655             if (ret != ACAMERA_OK) {
   1656                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
   1657                         cameraId, capture, ret);
   1658                 goto cleanup;
   1659             }
   1660         }
   1661 
   1662         // wait until all capture finished
   1663         for (int i = 0; i < 50; i++) {
   1664             usleep(100000); // sleep 100ms
   1665             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
   1666                 ALOGI("Session take ~%d ms to capture %d images",
   1667                         i*100, NUM_TEST_IMAGES);
   1668                 break;
   1669             }
   1670         }
   1671 
   1672         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
   1673             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
   1674                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
   1675             goto cleanup;
   1676         }
   1677 
   1678         ret = testCase.resetWithErrorLog();
   1679         if (ret != ACAMERA_OK) {
   1680             // Don't log error here. testcase did it
   1681             goto cleanup;
   1682         }
   1683 
   1684         usleep(100000); // sleep to give some time for callbacks to happen
   1685 
   1686         if (!testCase.isCameraAvailable(cameraId)) {
   1687             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1688             goto cleanup;
   1689         }
   1690     }
   1691 
   1692     ret = testCase.deInit();
   1693     if (ret != ACAMERA_OK) {
   1694         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1695         goto cleanup;
   1696     }
   1697 
   1698     pass = true;
   1699 
   1700 cleanup:
   1701     if (outPath != nullptr) {
   1702         env->ReleaseStringUTFChars(jOutPath, outPath);
   1703     }
   1704     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1705     if (!pass) {
   1706         throwAssertionError(env, errorString);
   1707     }
   1708     return pass;
   1709 }
   1710 
   1711 extern "C" jboolean
   1712 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
   1713 testJpegNative(
   1714         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
   1715     ALOGV("%s", __FUNCTION__);
   1716     return nativeImageReaderTestBase(env, jOutPath, ImageReaderListener::validateImageCb);
   1717 }
   1718 
   1719 
   1720 extern "C" jboolean
   1721 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
   1722 testImageReaderCloseAcquiredImagesNative(
   1723         JNIEnv* env, jclass /*clazz*/) {
   1724     ALOGV("%s", __FUNCTION__);
   1725     return nativeImageReaderTestBase(env, nullptr, ImageReaderListener::acquireImageCb);
   1726 }
   1727 
   1728 
   1729 extern "C" jboolean
   1730 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
   1731 testStillCaptureNative(
   1732         JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
   1733     ALOGV("%s", __FUNCTION__);
   1734     const int NUM_TEST_IMAGES = 10;
   1735     const int TEST_WIDTH  = 640;
   1736     const int TEST_HEIGHT = 480;
   1737     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
   1738     int numCameras = 0;
   1739     bool pass = false;
   1740     PreviewTestCase testCase;
   1741 
   1742     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
   1743     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
   1744 
   1745     camera_status_t ret = testCase.initWithErrorLog();
   1746     if (ret != ACAMERA_OK) {
   1747         // Don't log error here. testcase did it
   1748         goto cleanup;
   1749     }
   1750 
   1751     numCameras = testCase.getNumCameras();
   1752     if (numCameras < 0) {
   1753         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
   1754         goto cleanup;
   1755     }
   1756 
   1757     for (int i = 0; i < numCameras; i++) {
   1758         const char* cameraId = testCase.getCameraId(i);
   1759         if (cameraId == nullptr) {
   1760             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
   1761             goto cleanup;
   1762         }
   1763 
   1764         ret = testCase.openCamera(cameraId);
   1765         if (ret != ACAMERA_OK) {
   1766             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
   1767             goto cleanup;
   1768         }
   1769 
   1770         usleep(100000); // sleep to give some time for callbacks to happen
   1771 
   1772         if (testCase.isCameraAvailable(cameraId)) {
   1773             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
   1774             goto cleanup;
   1775         }
   1776 
   1777         ImageReaderListener readerListener;
   1778         AImageReader_ImageListener readerCb {
   1779             &readerListener,
   1780             ImageReaderListener::validateImageCb
   1781         };
   1782         readerListener.setDumpFilePathBase(outPath);
   1783         mediaRet = testCase.initImageReaderWithErrorLog(
   1784                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
   1785                 &readerCb);
   1786         if (mediaRet != AMEDIA_OK) {
   1787             // Don't log error here. testcase did it
   1788             goto cleanup;
   1789         }
   1790 
   1791         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
   1792         if (previewAnw == nullptr) {
   1793             LOG_ERROR(errorString, "Null ANW from preview surface!");
   1794             goto cleanup;
   1795         }
   1796 
   1797         ret = testCase.createCaptureSessionWithLog();
   1798         if (ret != ACAMERA_OK) {
   1799             // Don't log error here. testcase did it
   1800             goto cleanup;
   1801         }
   1802 
   1803         ret = testCase.createRequestsWithErrorLog();
   1804         if (ret != ACAMERA_OK) {
   1805             // Don't log error here. testcase did it
   1806             goto cleanup;
   1807         }
   1808 
   1809         ret = testCase.startPreview();
   1810         if (ret != ACAMERA_OK) {
   1811             LOG_ERROR(errorString, "Start preview failed!");
   1812             goto cleanup;
   1813         }
   1814 
   1815         // Let preview run some time
   1816         sleep(3);
   1817 
   1818         // Do some still capture
   1819         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
   1820             ret = testCase.takePicture();
   1821             if (ret != ACAMERA_OK) {
   1822                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
   1823                         cameraId, capture, ret);
   1824                 goto cleanup;
   1825             }
   1826         }
   1827 
   1828         // wait until all capture finished
   1829         for (int i = 0; i < 50; i++) {
   1830             usleep(100000); // sleep 100ms
   1831             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
   1832                 ALOGI("Session take ~%d ms to capture %d images",
   1833                         i*100, NUM_TEST_IMAGES);
   1834                 break;
   1835             }
   1836         }
   1837 
   1838         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
   1839             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
   1840                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
   1841             goto cleanup;
   1842         }
   1843 
   1844         ret = testCase.resetWithErrorLog();
   1845         if (ret != ACAMERA_OK) {
   1846             // Don't log error here. testcase did it
   1847             goto cleanup;
   1848         }
   1849 
   1850         usleep(100000); // sleep to give some time for callbacks to happen
   1851 
   1852         if (!testCase.isCameraAvailable(cameraId)) {
   1853             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
   1854             goto cleanup;
   1855         }
   1856     }
   1857 
   1858     ret = testCase.deInit();
   1859     if (ret != ACAMERA_OK) {
   1860         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
   1861         goto cleanup;
   1862     }
   1863 
   1864     pass = true;
   1865 cleanup:
   1866     env->ReleaseStringUTFChars(jOutPath, outPath);
   1867     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
   1868     if (!pass) {
   1869         throwAssertionError(env, errorString);
   1870     }
   1871     return pass;
   1872 }
   1873 
   1874