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:
onAvailable(void * obj,const char * cameraId)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 
onUnavailable(void * obj,const char * cameraId)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 
resetCount()73     void resetCount() {
74         std::lock_guard<std::mutex> lock(mMutex);
75         mOnAvailableCount = 0;
76         mOnUnavailableCount = 0;
77         return;
78     }
79 
getAvailableCount()80     int getAvailableCount() {
81         std::lock_guard<std::mutex> lock(mMutex);
82         return mOnAvailableCount;
83     }
84 
getUnavailableCount()85     int getUnavailableCount() {
86         std::lock_guard<std::mutex> lock(mMutex);
87         return mOnUnavailableCount;
88     }
89 
isAvailable(const char * cameraId)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:
onDisconnected(void * obj,ACameraDevice * device)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 
onError(void * obj,ACameraDevice * device,int errorCode)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:
onClosed(void * obj,ACameraCaptureSession * session)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 
onReady(void * obj,ACameraCaptureSession * session)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 
onActive(void * obj,ACameraCaptureSession * session)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 
isClosed()191     bool isClosed() {
192         std::lock_guard<std::mutex> lock(mMutex);
193         return mIsClosed;
194     }
195 
isIdle()196     bool isIdle() {
197         std::lock_guard<std::mutex> lock(mMutex);
198         return mIsIdle;
199     }
200 
isInError()201     bool isInError() {
202         std::lock_guard<std::mutex> lock(mMutex);
203         return mInError;
204     }
205 
onClosedCount()206     int onClosedCount()  {
207         std::lock_guard<std::mutex> lock(mMutex);
208         return mOnClosed;
209     }
210 
onReadyCount()211     int onReadyCount()  {
212         std::lock_guard<std::mutex> lock(mMutex);
213         return mOnReady;
214     }
215 
onActiveCount()216     int onActiveCount()  {
217         std::lock_guard<std::mutex> lock(mMutex);
218         return mOnActive;
219     }
220 
reset()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:
onImageAvailable(void * obj,AImageReader * reader)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 
onImageAvailableCount()323     int onImageAvailableCount() {
324         std::lock_guard<std::mutex> lock(mMutex);
325         return mOnImageAvailableCount;
326     }
327 
setDumpFilePathBase(const char * path)328     void setDumpFilePathBase(const char* path) {
329         std::lock_guard<std::mutex> lock(mMutex);
330         mDumpFilePathBase = path;
331     }
332 
reset()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:
StaticInfo(ACameraMetadata * chars)348     explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
349 
isColorOutputSupported()350     bool isColorOutputSupported() {
351         return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
352     }
353 
isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap)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:
~PreviewTestCase()370     ~PreviewTestCase() {
371         resetCamera();
372         deInit();
373         if (mCameraManager) {
374             ACameraManager_delete(mCameraManager);
375             mCameraManager = nullptr;
376         }
377     }
378 
PreviewTestCase()379     PreviewTestCase() {
380         // create is guaranteed to succeed;
381         createManager();
382     }
383 
384     // Free all resources except camera manager
resetCamera()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 
initWithErrorLog()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 
deInit()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 
getNumCameras()475     int getNumCameras() {
476         if (!mMgrInited || !mCameraIdList) {
477             return -1;
478         }
479         return mCameraIdList->numCameras;
480     }
481 
getCameraId(int idx)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 
openCamera(const char * cameraId)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 
closeCamera()498     camera_status_t closeCamera() {
499         camera_status_t ret = ACameraDevice_close(mDevice);
500         mDevice = nullptr;
501         return ret;
502     }
503 
isCameraAvailable(const char * cameraId)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 
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages)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 
initPreviewAnw(JNIEnv * env,jobject jSurface)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 
createCaptureSessionWithLog()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 
closeSession()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 
createRequestsWithErrorLog()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 
startPreview()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 
takePicture()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 
getReaderImageCount()752     int getReaderImageCount() {
753         return mReaderListener.onImageAvailableCount();
754     }
755 
resetWithErrorLog()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 
setDumpFilePathBase(const char * path)788     void setDumpFilePathBase(const char* path) {
789         mReaderListener.setDumpFilePathBase(path);
790     }
791 
getSessionListener()792     CaptureSessionListener* getSessionListener() {
793         return &mSessionListener;
794     }
795 
796   private:
createManager()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 
throwAssertionError(JNIEnv * env,const char * message)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
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)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
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)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
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)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
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)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
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass)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
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass)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
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface)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
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass,jobject jPreviewSurface)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
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath)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
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface)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