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 <chrono>
22 #include <condition_variable>
23 #include <string>
24 #include <map>
25 #include <mutex>
26 #include <vector>
27 #include <unistd.h>
28 #include <assert.h>
29 #include <jni.h>
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include <android/native_window_jni.h>
34 
35 #include "camera/NdkCameraError.h"
36 #include "camera/NdkCameraManager.h"
37 #include "camera/NdkCameraDevice.h"
38 #include "camera/NdkCameraCaptureSession.h"
39 #include "media/NdkImage.h"
40 #include "media/NdkImageReader.h"
41 
42 #define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
43                             ALOGE("%s", buf);
44 
45 namespace {
46     const int MAX_ERROR_STRING_LEN = 512;
47     char errorString[MAX_ERROR_STRING_LEN];
48 }
49 
50 class CameraServiceListener {
51   public:
onAvailable(void * obj,const char * cameraId)52     static void onAvailable(void* obj, const char* cameraId) {
53         ALOGV("Camera %s onAvailable", cameraId);
54         if (obj == nullptr) {
55             return;
56         }
57         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
58         std::lock_guard<std::mutex> lock(thiz->mMutex);
59         thiz->mOnAvailableCount++;
60         thiz->mAvailableMap[cameraId] = true;
61         return;
62     }
63 
onUnavailable(void * obj,const char * cameraId)64     static void onUnavailable(void* obj, const char* cameraId) {
65         ALOGV("Camera %s onUnavailable", cameraId);
66         if (obj == nullptr) {
67             return;
68         }
69         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
70         std::lock_guard<std::mutex> lock(thiz->mMutex);
71         thiz->mOnUnavailableCount++;
72         thiz->mAvailableMap[cameraId] = false;
73         return;
74     }
75 
resetCount()76     void resetCount() {
77         std::lock_guard<std::mutex> lock(mMutex);
78         mOnAvailableCount = 0;
79         mOnUnavailableCount = 0;
80         return;
81     }
82 
getAvailableCount()83     int getAvailableCount() {
84         std::lock_guard<std::mutex> lock(mMutex);
85         return mOnAvailableCount;
86     }
87 
getUnavailableCount()88     int getUnavailableCount() {
89         std::lock_guard<std::mutex> lock(mMutex);
90         return mOnUnavailableCount;
91     }
92 
isAvailable(const char * cameraId)93     bool isAvailable(const char* cameraId) {
94         std::lock_guard<std::mutex> lock(mMutex);
95         if (mAvailableMap.count(cameraId) == 0) {
96             return false;
97         }
98         return mAvailableMap[cameraId];
99     }
100 
101   private:
102     std::mutex mMutex;
103     int mOnAvailableCount = 0;
104     int mOnUnavailableCount = 0;
105     std::map<std::string, bool> mAvailableMap;
106 };
107 
108 class CameraDeviceListener {
109   public:
onDisconnected(void * obj,ACameraDevice * device)110     static void onDisconnected(void* obj, ACameraDevice* device) {
111         ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
112         if (obj == nullptr) {
113             return;
114         }
115         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
116         std::lock_guard<std::mutex> lock(thiz->mMutex);
117         thiz->mOnDisconnect++;
118         return;
119     }
120 
onError(void * obj,ACameraDevice * device,int errorCode)121     static void onError(void* obj, ACameraDevice* device, int errorCode) {
122         ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
123         if (obj == nullptr) {
124             return;
125         }
126         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
127         std::lock_guard<std::mutex> lock(thiz->mMutex);
128         thiz->mOnError++;
129         thiz->mLatestError = errorCode;
130         return;
131     }
132 
133   private:
134     std::mutex mMutex;
135     int mOnDisconnect = 0;
136     int mOnError = 0;
137     int mLatestError = 0;
138 };
139 
140 class CaptureSessionListener {
141 
142   public:
onClosed(void * obj,ACameraCaptureSession * session)143     static void onClosed(void* obj, ACameraCaptureSession *session) {
144         // TODO: might want an API to query cameraId even session is closed?
145         ALOGV("Session %p is closed!", session);
146         if (obj == nullptr) {
147             return;
148         }
149         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
150         std::lock_guard<std::mutex> lock(thiz->mMutex);
151         thiz->mIsClosed = true;
152         thiz->mOnClosed++; // Should never > 1
153     }
154 
onReady(void * obj,ACameraCaptureSession * session)155     static void onReady(void* obj, ACameraCaptureSession *session) {
156         ALOGV("%s", __FUNCTION__);
157         if (obj == nullptr) {
158             return;
159         }
160         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
161         std::lock_guard<std::mutex> lock(thiz->mMutex);
162         ACameraDevice* device = nullptr;
163         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
164         // There will be one onReady fired after session closed
165         if (ret != ACAMERA_OK && !thiz->mIsClosed) {
166             ALOGE("%s Getting camera device from session callback failed!",
167                     __FUNCTION__);
168             thiz->mInError = true;
169         }
170         ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
171         thiz->mIsIdle = true;
172         thiz->mOnReady++;
173     }
174 
onActive(void * obj,ACameraCaptureSession * session)175     static void onActive(void* obj, ACameraCaptureSession *session) {
176         ALOGV("%s", __FUNCTION__);
177         if (obj == nullptr) {
178             return;
179         }
180         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
181         std::lock_guard<std::mutex> lock(thiz->mMutex);
182         ACameraDevice* device = nullptr;
183         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
184         if (ret != ACAMERA_OK) {
185             ALOGE("%s Getting camera device from session callback failed!",
186                     __FUNCTION__);
187             thiz->mInError = true;
188         }
189         ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
190         thiz->mIsIdle = false;
191         thiz->mOnActive;
192     }
193 
isClosed()194     bool isClosed() {
195         std::lock_guard<std::mutex> lock(mMutex);
196         return mIsClosed;
197     }
198 
isIdle()199     bool isIdle() {
200         std::lock_guard<std::mutex> lock(mMutex);
201         return mIsIdle;
202     }
203 
isInError()204     bool isInError() {
205         std::lock_guard<std::mutex> lock(mMutex);
206         return mInError;
207     }
208 
onClosedCount()209     int onClosedCount()  {
210         std::lock_guard<std::mutex> lock(mMutex);
211         return mOnClosed;
212     }
213 
onReadyCount()214     int onReadyCount()  {
215         std::lock_guard<std::mutex> lock(mMutex);
216         return mOnReady;
217     }
218 
onActiveCount()219     int onActiveCount()  {
220         std::lock_guard<std::mutex> lock(mMutex);
221         return mOnActive;
222     }
223 
reset()224     void reset() {
225         std::lock_guard<std::mutex> lock(mMutex);
226         mIsClosed = false;
227         mIsIdle = true;
228         mInError = false;
229         mOnClosed = 0;
230         mOnReady = 0;
231         mOnActive = 0;
232     }
233 
234   private:
235     std::mutex mMutex;
236     bool mIsClosed = false;
237     bool mIsIdle = true;
238     bool mInError = false; // should always stay false
239     int mOnClosed = 0;
240     int mOnReady = 0;
241     int mOnActive = 0;
242 };
243 
244 class CaptureResultListener {
245   public:
~CaptureResultListener()246     ~CaptureResultListener() {
247         std::unique_lock<std::mutex> l(mMutex);
248         clearSavedRequestsLocked();
249     }
250 
onCaptureStart(void *,ACameraCaptureSession *,const ACaptureRequest *,int64_t)251     static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
252             const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
253         //Not used for now
254     }
255 
onCaptureProgressed(void *,ACameraCaptureSession *,ACaptureRequest *,const ACameraMetadata *)256     static void onCaptureProgressed(void* /*obj*/, ACameraCaptureSession* /*session*/,
257             ACaptureRequest* /*request*/, const ACameraMetadata* /*result*/) {
258         //Not used for now
259     }
260 
onCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result)261     static void onCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
262             ACaptureRequest* request, const ACameraMetadata* result) {
263         ALOGV("%s", __FUNCTION__);
264         if ((obj == nullptr) || (result == nullptr)) {
265             return;
266         }
267         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
268         std::lock_guard<std::mutex> lock(thiz->mMutex);
269         ACameraMetadata_const_entry entry;
270         auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
271         if (ret != ACAMERA_OK) {
272             ALOGE("Error: Sync frame number missing from result!");
273             return;
274         }
275 
276         if (thiz->mSaveCompletedRequests) {
277             thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
278         }
279 
280         thiz->mLastCompletedFrameNumber = entry.data.i64[0];
281         thiz->mResultCondition.notify_one();
282     }
283 
onCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ACameraCaptureFailure * failure)284     static void onCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
285             ACaptureRequest* /*request*/, ACameraCaptureFailure* failure) {
286         ALOGV("%s", __FUNCTION__);
287         if ((obj == nullptr) || (failure == nullptr)) {
288             return;
289         }
290         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
291         std::lock_guard<std::mutex> lock(thiz->mMutex);
292         thiz->mLastFailedFrameNumber = failure->frameNumber;
293         thiz->mResultCondition.notify_one();
294     }
295 
onCaptureSequenceCompleted(void * obj,ACameraCaptureSession *,int sequenceId,int64_t frameNumber)296     static void onCaptureSequenceCompleted(void* obj, ACameraCaptureSession* /*session*/,
297             int sequenceId, int64_t frameNumber) {
298         ALOGV("%s", __FUNCTION__);
299         if (obj == nullptr) {
300             return;
301         }
302         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
303         std::lock_guard<std::mutex> lock(thiz->mMutex);
304         thiz->mLastSequenceIdCompleted = sequenceId;
305         thiz->mLastSequenceFrameNumber = frameNumber;
306         thiz->mResultCondition.notify_one();
307     }
308 
onCaptureSequenceAborted(void *,ACameraCaptureSession *,int)309     static void onCaptureSequenceAborted(void* /*obj*/, ACameraCaptureSession* /*session*/,
310             int /*sequenceId*/) {
311         //Not used for now
312     }
313 
onCaptureBufferLost(void * obj,ACameraCaptureSession *,ACaptureRequest *,ANativeWindow *,int64_t frameNumber)314     static void onCaptureBufferLost(void* obj, ACameraCaptureSession* /*session*/,
315             ACaptureRequest* /*request*/, ANativeWindow* /*window*/, int64_t frameNumber) {
316         ALOGV("%s", __FUNCTION__);
317         if (obj == nullptr) {
318             return;
319         }
320         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
321         std::lock_guard<std::mutex> lock(thiz->mMutex);
322         thiz->mLastLostFrameNumber = frameNumber;
323         thiz->mResultCondition.notify_one();
324     }
325 
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)326     int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
327         int64_t ret = -1;
328         std::unique_lock<std::mutex> l(mMutex);
329 
330         while (mLastSequenceIdCompleted != sequenceId) {
331             auto timeout = std::chrono::system_clock::now() +
332                            std::chrono::seconds(timeoutSec);
333             if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
334                 break;
335             }
336         }
337 
338         if (mLastSequenceIdCompleted == sequenceId) {
339             ret = mLastSequenceFrameNumber;
340         }
341 
342         return ret;
343     }
344 
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)345     bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
346         bool ret = false;
347         std::unique_lock<std::mutex> l(mMutex);
348 
349         while ((mLastCompletedFrameNumber != frameNumber) &&
350                 (mLastLostFrameNumber != frameNumber) &&
351                 (mLastFailedFrameNumber != frameNumber)) {
352             auto timeout = std::chrono::system_clock::now() +
353                            std::chrono::seconds(timeoutSec);
354             if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
355                 break;
356             }
357         }
358 
359         if ((mLastCompletedFrameNumber == frameNumber) ||
360                 (mLastLostFrameNumber == frameNumber) ||
361                 (mLastFailedFrameNumber == frameNumber)) {
362             ret = true;
363         }
364 
365         return ret;
366     }
367 
setRequestSave(bool enable)368     void setRequestSave(bool enable) {
369         std::unique_lock<std::mutex> l(mMutex);
370         if (!enable) {
371             clearSavedRequestsLocked();
372         }
373         mSaveCompletedRequests = enable;
374     }
375 
376     // The lifecycle of returned ACaptureRequest* is still managed by CaptureResultListener
getCompletedRequests(std::vector<ACaptureRequest * > * out)377     void getCompletedRequests(std::vector<ACaptureRequest*>* out) {
378         std::unique_lock<std::mutex> l(mMutex);
379         *out = mCompletedRequests;
380     }
381 
reset()382     void reset() {
383         std::lock_guard<std::mutex> lock(mMutex);
384         mLastSequenceIdCompleted = -1;
385         mLastSequenceFrameNumber = -1;
386         mLastCompletedFrameNumber = -1;
387         mLastLostFrameNumber = -1;
388         mLastFailedFrameNumber = -1;
389         mSaveCompletedRequests = false;
390         clearSavedRequestsLocked();
391     }
392 
393   private:
394     std::mutex mMutex;
395     std::condition_variable mResultCondition;
396     int mLastSequenceIdCompleted = -1;
397     int64_t mLastSequenceFrameNumber = -1;
398     int64_t mLastCompletedFrameNumber = -1;
399     int64_t mLastLostFrameNumber = -1;
400     int64_t mLastFailedFrameNumber = -1;
401     bool    mSaveCompletedRequests = false;
402     std::vector<ACaptureRequest*> mCompletedRequests;
403 
clearSavedRequestsLocked()404     void clearSavedRequestsLocked() {
405         for (ACaptureRequest* req : mCompletedRequests) {
406             ACaptureRequest_free(req);
407         }
408         mCompletedRequests.clear();
409     }
410 };
411 
412 class ImageReaderListener {
413   public:
414     // count, acquire, validate, and delete AImage when a new image is available
validateImageCb(void * obj,AImageReader * reader)415     static void validateImageCb(void* obj, AImageReader* reader) {
416         ALOGV("%s", __FUNCTION__);
417         if (obj == nullptr) {
418             return;
419         }
420         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
421         std::lock_guard<std::mutex> lock(thiz->mMutex);
422         thiz->mOnImageAvailableCount++;
423 
424         AImage* img = nullptr;
425         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
426         if (ret != AMEDIA_OK || img == nullptr) {
427             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
428                     __FUNCTION__, reader, ret, img);
429             return;
430         }
431 
432         // TODO: validate image content
433         int32_t format = -1;
434         ret = AImage_getFormat(img, &format);
435         if (ret != AMEDIA_OK || format == -1) {
436             ALOGE("%s: get format for image %p failed! ret: %d, format %d",
437                     __FUNCTION__, img, ret, format);
438         }
439 
440         // Save jpeg to SD card
441         if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
442             int32_t numPlanes = 0;
443             ret = AImage_getNumberOfPlanes(img, &numPlanes);
444             if (ret != AMEDIA_OK || numPlanes != 1) {
445                 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
446                         __FUNCTION__, img, ret, numPlanes);
447                 AImage_delete(img);
448                 return;
449             }
450 
451             int32_t width = -1, height = -1;
452             ret = AImage_getWidth(img, &width);
453             if (ret != AMEDIA_OK || width <= 0) {
454                 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
455                         __FUNCTION__, img, ret, width);
456                 AImage_delete(img);
457                 return;
458             }
459 
460             ret = AImage_getHeight(img, &height);
461             if (ret != AMEDIA_OK || height <= 0) {
462                 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
463                         __FUNCTION__, img, ret, height);
464                 AImage_delete(img);
465                 return;
466             }
467 
468             uint8_t* data = nullptr;
469             int dataLength = 0;
470             ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
471             if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
472                 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
473                         __FUNCTION__, img, ret, data, dataLength);
474                 AImage_delete(img);
475                 return;
476             }
477 
478 #if 0
479             char dumpFilePath[512];
480             sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
481             ALOGI("Writing jpeg file to %s", dumpFilePath);
482             FILE* file = fopen(dumpFilePath,"w+");
483 
484             if (file != nullptr) {
485                 fwrite(data, 1, dataLength, file);
486                 fflush(file);
487                 fclose(file);
488             }
489 #endif
490         }
491 
492         AImage_delete(img);
493     }
494 
495     // count, acquire image but not delete the image
acquireImageCb(void * obj,AImageReader * reader)496     static void acquireImageCb(void* obj, AImageReader* reader) {
497         ALOGV("%s", __FUNCTION__);
498         if (obj == nullptr) {
499             return;
500         }
501         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
502         std::lock_guard<std::mutex> lock(thiz->mMutex);
503         thiz->mOnImageAvailableCount++;
504 
505         // Acquire, but not closing.
506         AImage* img = nullptr;
507         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
508         if (ret != AMEDIA_OK || img == nullptr) {
509             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
510                     __FUNCTION__, reader, ret, img);
511             return;
512         }
513         return;
514     }
515 
onImageAvailableCount()516     int onImageAvailableCount() {
517         std::lock_guard<std::mutex> lock(mMutex);
518         return mOnImageAvailableCount;
519     }
520 
setDumpFilePathBase(const char * path)521     void setDumpFilePathBase(const char* path) {
522         std::lock_guard<std::mutex> lock(mMutex);
523         mDumpFilePathBase = path;
524     }
525 
526   private:
527     // TODO: add mReader to make sure each listener is associated to one reader?
528     std::mutex mMutex;
529     int mOnImageAvailableCount = 0;
530     const char* mDumpFilePathBase = nullptr;
531 };
532 
533 class StaticInfo {
534   public:
StaticInfo(ACameraMetadata * chars)535     explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
536 
isColorOutputSupported()537     bool isColorOutputSupported() {
538         return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
539     }
540 
isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap)541     bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
542         ACameraMetadata_const_entry entry;
543         ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
544         for (uint32_t i = 0; i < entry.count; i++) {
545             if (entry.data.u8[i] == cap) {
546                 return true;
547             }
548         }
549         return false;
550     }
551   private:
552     const ACameraMetadata* mChars;
553 };
554 
555 class PreviewTestCase {
556   public:
~PreviewTestCase()557     ~PreviewTestCase() {
558         resetCamera();
559         deInit();
560         if (mCameraManager) {
561             ACameraManager_delete(mCameraManager);
562             mCameraManager = nullptr;
563         }
564     }
565 
PreviewTestCase()566     PreviewTestCase() {
567         // create is guaranteed to succeed;
568         createManager();
569     }
570 
571     // Free all resources except camera manager
resetCamera()572     void resetCamera() {
573         mSessionListener.reset();
574         mResultListener.reset();
575         if (mSession) {
576             ACameraCaptureSession_close(mSession);
577             mSession = nullptr;
578         }
579         if (mDevice) {
580             ACameraDevice_close(mDevice);
581             mDevice = nullptr;
582         }
583         if (mImgReader) {
584             AImageReader_delete(mImgReader);
585             // No need to call ANativeWindow_release on imageReaderAnw
586             mImgReaderAnw = nullptr;
587             mImgReader = nullptr;
588         }
589         if (mPreviewAnw) {
590             ANativeWindow_release(mPreviewAnw);
591             mPreviewAnw = nullptr;
592         }
593         if (mOutputs) {
594             ACaptureSessionOutputContainer_free(mOutputs);
595             mOutputs = nullptr;
596         }
597         if (mPreviewOutput) {
598             ACaptureSessionOutput_free(mPreviewOutput);
599             mPreviewOutput = nullptr;
600         }
601         if (mImgReaderOutput) {
602             ACaptureSessionOutput_free(mImgReaderOutput);
603             mImgReaderOutput = nullptr;
604         }
605         if (mPreviewRequest) {
606             ACaptureRequest_free(mPreviewRequest);
607             mPreviewRequest = nullptr;
608         }
609         if (mStillRequest) {
610             ACaptureRequest_free(mStillRequest);
611             mStillRequest = nullptr;
612         }
613         if (mReqPreviewOutput) {
614             ACameraOutputTarget_free(mReqPreviewOutput);
615             mReqPreviewOutput = nullptr;
616         }
617         if (mReqImgReaderOutput) {
618             ACameraOutputTarget_free(mReqImgReaderOutput);
619             mReqImgReaderOutput = nullptr;
620         }
621 
622         mImgReaderInited = false;
623         mPreviewInited = false;
624     }
625 
initWithErrorLog()626     camera_status_t initWithErrorLog() {
627         camera_status_t ret = ACameraManager_getCameraIdList(
628                 mCameraManager, &mCameraIdList);
629         if (ret != ACAMERA_OK) {
630             LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
631             return ret;
632         }
633         ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
634         if (ret != ACAMERA_OK) {
635             LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
636             return ret;
637         }
638         mMgrInited = true;
639         return ACAMERA_OK;
640     }
641 
deInit()642     camera_status_t deInit () {
643         if (!mMgrInited) {
644             return ACAMERA_OK;
645         }
646 
647         camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
648                 mCameraManager, &mServiceCb);
649         if (ret != ACAMERA_OK) {
650             ALOGE("Unregister availability callback failed: ret %d", ret);
651             return ret;
652         }
653 
654         if (mCameraIdList) {
655             ACameraManager_deleteCameraIdList(mCameraIdList);
656             mCameraIdList = nullptr;
657         }
658         mMgrInited = false;
659         return ACAMERA_OK;
660     }
661 
getNumCameras()662     int getNumCameras() {
663         if (!mMgrInited || !mCameraIdList) {
664             return -1;
665         }
666         return mCameraIdList->numCameras;
667     }
668 
getCameraId(int idx)669     const char* getCameraId(int idx) {
670         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
671             return nullptr;
672         }
673         return mCameraIdList->cameraIds[idx];
674     }
675 
updateOutput(JNIEnv * env,ACaptureSessionOutput * output)676     camera_status_t updateOutput(JNIEnv* env, ACaptureSessionOutput *output) {
677         if (mSession == nullptr) {
678             ALOGE("Testcase cannot update output configuration session %p",
679                     mSession);
680             return ACAMERA_ERROR_UNKNOWN;
681         }
682 
683         return ACameraCaptureSession_updateSharedOutput(mSession, output);
684     }
685 
openCamera(const char * cameraId)686     camera_status_t openCamera(const char* cameraId) {
687         if (mDevice) {
688             ALOGE("Cannot open camera before closing previously open one");
689             return ACAMERA_ERROR_INVALID_PARAMETER;
690         }
691         mCameraId = cameraId;
692         return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
693     }
694 
closeCamera()695     camera_status_t closeCamera() {
696         camera_status_t ret = ACameraDevice_close(mDevice);
697         mDevice = nullptr;
698         return ret;
699     }
700 
isCameraAvailable(const char * cameraId)701     bool isCameraAvailable(const char* cameraId) {
702         if (!mMgrInited) {
703             ALOGE("Camera service listener has not been registered!");
704         }
705         return mServiceListener.isAvailable(cameraId);
706     }
707 
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener)708     media_status_t initImageReaderWithErrorLog(
709             int32_t width, int32_t height, int32_t format, int32_t maxImages,
710             AImageReader_ImageListener* listener) {
711         if (mImgReader || mImgReaderAnw) {
712             LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
713             return AMEDIA_ERROR_UNKNOWN;
714         }
715 
716         media_status_t ret = AImageReader_new(
717                 width, height, format,
718                 maxImages, &mImgReader);
719         if (ret != AMEDIA_OK) {
720             LOG_ERROR(errorString, "Create image reader. ret %d", ret);
721             return ret;
722         }
723         if (mImgReader == nullptr) {
724             LOG_ERROR(errorString, "null image reader created");
725             return AMEDIA_ERROR_UNKNOWN;
726         }
727 
728         ret = AImageReader_setImageListener(mImgReader, listener);
729         if (ret != AMEDIA_OK) {
730             LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
731             return ret;
732         }
733 
734         ret = AImageReader_getWindow(mImgReader, &mImgReaderAnw);
735         if (ret != AMEDIA_OK) {
736             LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
737             return ret;
738         }
739         if (mImgReaderAnw == nullptr) {
740             LOG_ERROR(errorString, "Null ANW from AImageReader!");
741             return AMEDIA_ERROR_UNKNOWN;
742         }
743         mImgReaderInited = true;
744         return AMEDIA_OK;
745     }
746 
initPreviewAnw(JNIEnv * env,jobject jSurface)747     ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
748         if (mPreviewAnw) {
749             ALOGE("Cannot init preview twice!");
750             return nullptr;
751         }
752         mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
753         mPreviewInited = true;
754         return mPreviewAnw;
755     }
756 
createCaptureSessionWithLog(bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)757     camera_status_t createCaptureSessionWithLog(bool isPreviewShared = false,
758             ACaptureRequest *sessionParameters = nullptr) {
759         if (mSession) {
760             LOG_ERROR(errorString, "Cannot create session before closing existing one");
761             return ACAMERA_ERROR_UNKNOWN;
762         }
763 
764         if (!mMgrInited || (!mImgReaderInited && !mPreviewInited)) {
765             LOG_ERROR(errorString, "Cannot create session. mgrInit %d readerInit %d previewInit %d",
766                     mMgrInited, mImgReaderInited, mPreviewInited);
767             return ACAMERA_ERROR_UNKNOWN;
768         }
769 
770         camera_status_t ret = ACaptureSessionOutputContainer_create(&mOutputs);
771         if (ret != ACAMERA_OK) {
772             LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
773             return ret;
774         }
775 
776         if (mImgReaderInited) {
777             ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
778             if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
779                 LOG_ERROR(errorString,
780                         "Sesssion image reader output create fail! ret %d output %p",
781                         ret, mImgReaderOutput);
782                 if (ret == ACAMERA_OK) {
783                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
784                 }
785                 return ret;
786             }
787 
788             ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
789             if (ret != ACAMERA_OK) {
790                 LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
791                 return ret;
792             }
793         }
794 
795         if (mPreviewInited) {
796             if (isPreviewShared) {
797                 ret = ACaptureSessionSharedOutput_create(mPreviewAnw, &mPreviewOutput);
798             } else {
799                 ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
800             }
801             if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
802                 LOG_ERROR(errorString,
803                         "Sesssion preview output create fail! ret %d output %p",
804                         ret, mPreviewOutput);
805                 if (ret == ACAMERA_OK) {
806                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
807                 }
808                 return ret;
809             }
810 
811             ret = ACaptureSessionOutputContainer_add(mOutputs, mPreviewOutput);
812             if (ret != ACAMERA_OK) {
813                 LOG_ERROR(errorString, "Sesssion preview output add failed! ret %d", ret);
814                 return ret;
815             }
816         }
817 
818         ret = ACameraDevice_createCaptureSessionWithSessionParameters(
819                 mDevice, mOutputs, sessionParameters, &mSessionCb, &mSession);
820         if (ret != ACAMERA_OK || mSession == nullptr) {
821             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
822                     mCameraId, ret, mSession);
823             if (ret == ACAMERA_OK) {
824                 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
825             }
826             return ret;
827         }
828 
829         return ACAMERA_OK;
830     }
831 
closeSession()832     void closeSession() {
833         if (mSession != nullptr) {
834             ACameraCaptureSession_close(mSession);
835         }
836         if (mOutputs) {
837             ACaptureSessionOutputContainer_free(mOutputs);
838             mOutputs = nullptr;
839         }
840         if (mPreviewOutput) {
841             ACaptureSessionOutput_free(mPreviewOutput);
842             mPreviewOutput = nullptr;
843         }
844         if (mImgReaderOutput) {
845             ACaptureSessionOutput_free(mImgReaderOutput);
846             mImgReaderOutput = nullptr;
847         }
848         mSession = nullptr;
849     }
850 
createRequestsWithErrorLog()851     camera_status_t createRequestsWithErrorLog() {
852         if (mPreviewRequest || mStillRequest) {
853             LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
854             return ACAMERA_ERROR_UNKNOWN;
855         }
856 
857         if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
858             LOG_ERROR(errorString,
859                     "Cannot create request. device %p previewInit %d readeInit %d",
860                     mDevice, mPreviewInited, mImgReaderInited);
861             return ACAMERA_ERROR_UNKNOWN;
862         }
863 
864         camera_status_t ret;
865         if (mPreviewInited) {
866             ret = ACameraDevice_createCaptureRequest(
867                     mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
868             if (ret != ACAMERA_OK) {
869                 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
870                         mCameraId, ret);
871                 return ret;
872             }
873 
874             ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
875             if (ret != ACAMERA_OK) {
876                 LOG_ERROR(errorString,
877                         "Camera %s create request preview output target failed. ret %d",
878                         mCameraId, ret);
879                 return ret;
880             }
881 
882             ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
883             if (ret != ACAMERA_OK) {
884                 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
885                         mCameraId, ret);
886                 return ret;
887             }
888         } else {
889             ALOGI("Preview not inited. Will not create preview request!");
890         }
891 
892         if (mImgReaderInited) {
893             ret = ACameraDevice_createCaptureRequest(
894                     mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
895             if (ret != ACAMERA_OK) {
896                 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
897                         mCameraId, ret);
898                 return ret;
899             }
900 
901             ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
902             if (ret != ACAMERA_OK) {
903                 LOG_ERROR(errorString,
904                         "Camera %s create request reader output target failed. ret %d",
905                         mCameraId, ret);
906                 return ret;
907             }
908 
909             ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
910             if (ret != ACAMERA_OK) {
911                 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
912                         mCameraId, ret);
913                 return ret;
914             }
915 
916             if (mPreviewInited) {
917                 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
918                 if (ret != ACAMERA_OK) {
919                     LOG_ERROR(errorString,
920                             "Camera %s add still request preview output failed. ret %d",
921                             mCameraId, ret);
922                     return ret;
923                 }
924             }
925         } else {
926             ALOGI("AImageReader not inited. Will not create still request!");
927         }
928 
929         return ACAMERA_OK;
930     }
931 
932     // The output ACaptureRequest* is still managed by testcase class
getStillRequest(ACaptureRequest ** out)933     camera_status_t getStillRequest(ACaptureRequest** out) {
934         if (mStillRequest == nullptr) {
935             ALOGE("Camera %s Still capture request hasn't been created", mCameraId);
936             return ACAMERA_ERROR_INVALID_PARAMETER;
937         }
938         *out = mStillRequest;
939         return ACAMERA_OK;
940     }
941 
getPreviewRequest(ACaptureRequest ** out)942     camera_status_t getPreviewRequest(ACaptureRequest** out) {
943         if (mPreviewRequest == nullptr) {
944             ALOGE("Camera %s Preview capture request hasn't been created", mCameraId);
945             return ACAMERA_ERROR_INVALID_PARAMETER;
946         }
947         *out = mPreviewRequest;
948         return ACAMERA_OK;
949     }
950 
startPreview(int * sequenceId=nullptr)951     camera_status_t startPreview(int *sequenceId = nullptr) {
952         if (mSession == nullptr || mPreviewRequest == nullptr) {
953             ALOGE("Testcase cannot start preview: session %p, preview request %p",
954                     mSession, mPreviewRequest);
955             return ACAMERA_ERROR_UNKNOWN;
956         }
957         int previewSeqId;
958         camera_status_t ret;
959         if (sequenceId == nullptr) {
960             ret = ACameraCaptureSession_setRepeatingRequest(
961                    mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
962         } else {
963             ret = ACameraCaptureSession_setRepeatingRequest(
964                    mSession, &mResultCb, 1, &mPreviewRequest, sequenceId);
965         }
966         return ret;
967     }
968 
updateRepeatingRequest(ACaptureRequest * updatedRequest,int * sequenceId=nullptr)969     camera_status_t updateRepeatingRequest(ACaptureRequest *updatedRequest,
970             int *sequenceId = nullptr) {
971         if (mSession == nullptr || updatedRequest == nullptr) {
972             ALOGE("Testcase cannot update repeating request: session %p, updated request %p",
973                     mSession, updatedRequest);
974             return ACAMERA_ERROR_UNKNOWN;
975         }
976 
977         int previewSeqId;
978         camera_status_t ret;
979         if (sequenceId == nullptr) {
980             ret = ACameraCaptureSession_setRepeatingRequest(
981                     mSession, nullptr, 1, &updatedRequest, &previewSeqId);
982         } else {
983             ret = ACameraCaptureSession_setRepeatingRequest(
984                     mSession, &mResultCb, 1, &updatedRequest, sequenceId);
985         }
986         return ret;
987     }
988 
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)989     int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
990         return mResultListener.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
991     }
992 
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)993     bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
994         return mResultListener.waitForFrameNumber(frameNumber, timeoutSec);
995     }
996 
takePicture()997     camera_status_t takePicture() {
998         if (mSession == nullptr || mStillRequest == nullptr) {
999             ALOGE("Testcase cannot take picture: session %p, still request %p",
1000                     mSession, mStillRequest);
1001             return ACAMERA_ERROR_UNKNOWN;
1002         }
1003         int seqId;
1004         return ACameraCaptureSession_capture(
1005                 mSession, nullptr, 1, &mStillRequest, &seqId);
1006     }
1007 
capture(ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * listener,int * seqId)1008     camera_status_t capture(ACaptureRequest* request,
1009             ACameraCaptureSession_captureCallbacks* listener,
1010             /*out*/int* seqId) {
1011         if (mSession == nullptr || request == nullptr) {
1012             ALOGE("Testcase cannot capture session: session %p, request %p",
1013                     mSession, request);
1014             return ACAMERA_ERROR_UNKNOWN;
1015         }
1016         return ACameraCaptureSession_capture(
1017                 mSession, listener, 1, &request, seqId);
1018     }
1019 
resetWithErrorLog()1020     camera_status_t resetWithErrorLog() {
1021         camera_status_t ret;
1022 
1023         closeSession();
1024 
1025         for (int i = 0; i < 50; i++) {
1026             usleep(100000); // sleep 100ms
1027             if (mSessionListener.isClosed()) {
1028                 ALOGI("Session take ~%d ms to close", i*100);
1029                 break;
1030             }
1031         }
1032 
1033         if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
1034             LOG_ERROR(errorString,
1035                     "Session for camera %s close error. isClosde %d close count %d",
1036                     mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
1037             return ACAMERA_ERROR_UNKNOWN;
1038         }
1039         mSessionListener.reset();
1040         mResultListener.reset();
1041 
1042         ret = closeCamera();
1043         if (ret != ACAMERA_OK) {
1044             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
1045             return ret;
1046         }
1047 
1048         resetCamera();
1049         return ACAMERA_OK;
1050     }
1051 
getSessionListener()1052     CaptureSessionListener* getSessionListener() {
1053         return &mSessionListener;
1054     }
1055 
getCameraDevice()1056     ACameraDevice* getCameraDevice() {
1057         return mDevice;
1058     }
1059 
getPreviewOutput()1060     ACaptureSessionOutput *getPreviewOutput() {
1061         return mPreviewOutput;
1062     }
1063 
1064   private:
createManager()1065     ACameraManager* createManager() {
1066         if (!mCameraManager) {
1067             mCameraManager = ACameraManager_create();
1068         }
1069         return mCameraManager;
1070     }
1071 
1072     CameraServiceListener mServiceListener;
1073     ACameraManager_AvailabilityCallbacks mServiceCb {
1074         &mServiceListener,
1075         CameraServiceListener::onAvailable,
1076         CameraServiceListener::onUnavailable
1077     };
1078     CameraDeviceListener mDeviceListener;
1079     ACameraDevice_StateCallbacks mDeviceCb {
1080         &mDeviceListener,
1081         CameraDeviceListener::onDisconnected,
1082         CameraDeviceListener::onError
1083     };
1084     CaptureSessionListener mSessionListener;
1085     ACameraCaptureSession_stateCallbacks mSessionCb {
1086         &mSessionListener,
1087         CaptureSessionListener::onClosed,
1088         CaptureSessionListener::onReady,
1089         CaptureSessionListener::onActive
1090     };
1091 
1092     CaptureResultListener mResultListener;
1093     ACameraCaptureSession_captureCallbacks mResultCb {
1094         &mResultListener,
1095         CaptureResultListener::onCaptureStart,
1096         CaptureResultListener::onCaptureProgressed,
1097         CaptureResultListener::onCaptureCompleted,
1098         CaptureResultListener::onCaptureFailed,
1099         CaptureResultListener::onCaptureSequenceCompleted,
1100         CaptureResultListener::onCaptureSequenceAborted,
1101         CaptureResultListener::onCaptureBufferLost
1102     };
1103 
1104     ACameraIdList* mCameraIdList = nullptr;
1105     ACameraDevice* mDevice = nullptr;
1106     AImageReader* mImgReader = nullptr;
1107     ANativeWindow* mImgReaderAnw = nullptr;
1108     ANativeWindow* mPreviewAnw = nullptr;
1109     ACameraManager* mCameraManager = nullptr;
1110     ACaptureSessionOutputContainer* mOutputs = nullptr;
1111     ACaptureSessionOutput* mPreviewOutput = nullptr;
1112     ACaptureSessionOutput* mImgReaderOutput = nullptr;
1113     ACameraCaptureSession* mSession = nullptr;
1114     ACaptureRequest* mPreviewRequest = nullptr;
1115     ACaptureRequest* mStillRequest = nullptr;
1116     ACameraOutputTarget* mReqPreviewOutput = nullptr;
1117     ACameraOutputTarget* mReqImgReaderOutput = nullptr;
1118     const char* mCameraId;
1119 
1120     bool mMgrInited = false; // cameraId, serviceListener
1121     bool mImgReaderInited = false;
1122     bool mPreviewInited = false;
1123 };
1124 
throwAssertionError(JNIEnv * env,const char * message)1125 jint throwAssertionError(JNIEnv* env, const char* message)
1126 {
1127     jclass assertionClass;
1128     const char* className = "junit/framework/AssertionFailedError";
1129 
1130     assertionClass = env->FindClass(className);
1131     if (assertionClass == nullptr) {
1132         ALOGE("Native throw error: cannot find class %s", className);
1133         return -1;
1134     }
1135     return env->ThrowNew(assertionClass, message);
1136 }
1137 
1138 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)1139 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1140 testCameraManagerGetAndCloseNative(
1141         JNIEnv* env, jclass /*clazz*/) {
1142     bool pass = false;
1143     ALOGV("%s", __FUNCTION__);
1144     ACameraManager* cameraManager2 = nullptr;
1145     ACameraManager* cameraManager3 = nullptr;
1146     ACameraManager* cameraManager4 = nullptr;
1147     camera_status_t ret = ACAMERA_OK;
1148     ACameraManager* cameraManager = ACameraManager_create();
1149     if (cameraManager == nullptr) {
1150         LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
1151         goto cleanup;
1152     }
1153     ACameraManager_delete(cameraManager);
1154     cameraManager = nullptr;
1155 
1156     // Test get/close multiple instances
1157     cameraManager = ACameraManager_create();
1158     cameraManager2 = ACameraManager_create();
1159     if (cameraManager2 == nullptr) {
1160         LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
1161         goto cleanup;
1162     }
1163     ACameraManager_delete(cameraManager);
1164     cameraManager = nullptr;
1165     cameraManager3 = ACameraManager_create();
1166     if (cameraManager3 == nullptr) {
1167         LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
1168         goto cleanup;
1169     }
1170     cameraManager4 = ACameraManager_create();
1171         if (cameraManager4 == nullptr) {
1172         LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
1173         goto cleanup;
1174     }
1175     ACameraManager_delete(cameraManager3);
1176     ACameraManager_delete(cameraManager2);
1177     ACameraManager_delete(cameraManager4);
1178 
1179     pass = true;
1180 cleanup:
1181     if (cameraManager) {
1182         ACameraManager_delete(cameraManager);
1183     }
1184     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1185     if (!pass) {
1186         throwAssertionError(env, errorString);
1187     }
1188     return pass;
1189 }
1190 
1191 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)1192 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1193 testCameraManagerGetCameraIdsNative(
1194         JNIEnv* env, jclass /*clazz*/) {
1195     ALOGV("%s", __FUNCTION__);
1196     bool pass = false;
1197     ACameraManager* mgr = ACameraManager_create();
1198     ACameraIdList *cameraIdList = nullptr;
1199     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1200     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1201         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1202                 ret, cameraIdList);
1203         goto cleanup;
1204     }
1205     ALOGI("Number of cameras: %d", cameraIdList->numCameras);
1206     for (int i = 0; i < cameraIdList->numCameras; i++) {
1207         ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
1208     }
1209     ACameraManager_deleteCameraIdList(cameraIdList);
1210     cameraIdList = nullptr;
1211 
1212     pass = true;
1213 cleanup:
1214     if (mgr) {
1215         ACameraManager_delete(mgr);
1216     }
1217     if (cameraIdList) {
1218         ACameraManager_deleteCameraIdList(cameraIdList);
1219     }
1220     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1221     if (!pass) {
1222         throwAssertionError(env, errorString);
1223     }
1224     return pass;
1225 }
1226 
1227 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)1228 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1229 testCameraManagerAvailabilityCallbackNative(
1230         JNIEnv* env, jclass /*clazz*/) {
1231     ALOGV("%s", __FUNCTION__);
1232     bool pass = false;
1233     ACameraManager* mgr = ACameraManager_create();
1234     ACameraIdList *cameraIdList = nullptr;
1235     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1236     int numCameras = cameraIdList->numCameras;
1237     CameraServiceListener listener;
1238     ACameraManager_AvailabilityCallbacks cbs {
1239             &listener,
1240             CameraServiceListener::onAvailable,
1241             CameraServiceListener::onUnavailable};
1242     ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
1243     if (ret != ACAMERA_OK) {
1244         LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
1245         goto cleanup;
1246     }
1247     sleep(1); // sleep a second to give some time for callbacks to happen
1248 
1249     // Should at least get onAvailable for each camera once
1250     if (listener.getAvailableCount() < numCameras) {
1251         LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
1252                 numCameras, listener.getAvailableCount());
1253         goto cleanup;
1254     }
1255 
1256     ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
1257     if (ret != ACAMERA_OK) {
1258         LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
1259         goto cleanup;
1260     }
1261     pass = true;
1262 cleanup:
1263     if (cameraIdList) {
1264         ACameraManager_deleteCameraIdList(cameraIdList);
1265     }
1266     if (mgr) {
1267         ACameraManager_delete(mgr);
1268     }
1269     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1270     if (!pass) {
1271         throwAssertionError(env, errorString);
1272     }
1273     return pass;
1274 }
1275 
1276 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)1277 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1278 testCameraManagerCharacteristicsNative(
1279         JNIEnv* env, jclass /*clazz*/) {
1280     ALOGV("%s", __FUNCTION__);
1281     bool pass = false;
1282     ACameraManager* mgr = ACameraManager_create();
1283     ACameraIdList *cameraIdList = nullptr;
1284     ACameraMetadata* chars = nullptr;
1285     int numCameras = 0;
1286     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1287     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1288         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1289                 ret, cameraIdList);
1290         goto cleanup;
1291     }
1292     numCameras = cameraIdList->numCameras;
1293 
1294     for (int i = 0; i < numCameras; i++) {
1295         ret = ACameraManager_getCameraCharacteristics(
1296                 mgr, cameraIdList->cameraIds[i], &chars);
1297         if (ret != ACAMERA_OK) {
1298             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1299             goto cleanup;
1300         }
1301 
1302         int32_t numTags = 0;
1303         const uint32_t* tags = nullptr;
1304         ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
1305         if (ret != ACAMERA_OK) {
1306             LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
1307             goto cleanup;
1308         }
1309 
1310         for (int tid = 0; tid < numTags; tid++) {
1311             uint32_t tagId = tags[tid];
1312             ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
1313             uint32_t sectionId = tagId >> 16;
1314             if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
1315                 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
1316                 goto cleanup;
1317             }
1318         }
1319 
1320         ACameraMetadata_const_entry entry;
1321         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
1322         if (ret != ACAMERA_OK) {
1323             LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
1324             goto cleanup;
1325         }
1326 
1327         // Check the entry is actually legit
1328         if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
1329                 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
1330             LOG_ERROR(errorString,
1331                     "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
1332                     "type %d (expected %d), data %p (expected not null)",
1333                     entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
1334                     entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
1335             goto cleanup;
1336         }
1337         // All camera supports BC except depth only cameras
1338         bool supportBC = false, supportDepth = false;
1339         for (uint32_t i = 0; i < entry.count; i++) {
1340             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1341                 supportBC = true;
1342             }
1343             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
1344                 supportDepth = true;
1345             }
1346         }
1347         if (!(supportBC || supportDepth)) {
1348             LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
1349                     cameraIdList->cameraIds[i]);
1350             goto cleanup;
1351         }
1352 
1353         // Check get unknown value fails
1354         uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
1355         ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
1356         if (ret == ACAMERA_OK) {
1357             LOG_ERROR(errorString, "Error: get unknown tag should fail!");
1358             goto cleanup;
1359         }
1360 
1361         ACameraMetadata_free(chars);
1362         chars = nullptr;
1363     }
1364 
1365     pass = true;
1366 cleanup:
1367     if (chars) {
1368         ACameraMetadata_free(chars);
1369     }
1370     ACameraManager_deleteCameraIdList(cameraIdList);
1371     ACameraManager_delete(mgr);
1372     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1373     if (!pass) {
1374         throwAssertionError(env, errorString);
1375     }
1376     return pass;
1377 }
1378 
1379 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass)1380 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1381 testCameraDeviceOpenAndCloseNative(
1382         JNIEnv* env, jclass /*clazz*/) {
1383     ALOGV("%s", __FUNCTION__);
1384     int numCameras = 0;
1385     bool pass = false;
1386     PreviewTestCase testCase;
1387 
1388     camera_status_t ret = testCase.initWithErrorLog();
1389     if (ret != ACAMERA_OK) {
1390         // Don't log error here. testcase did it
1391         goto cleanup;
1392     }
1393 
1394     numCameras = testCase.getNumCameras();
1395     if (numCameras < 0) {
1396         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1397         goto cleanup;
1398     }
1399 
1400     for (int i = 0; i < numCameras; i++) {
1401         const char* cameraId = testCase.getCameraId(i);
1402         if (cameraId == nullptr) {
1403             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1404             goto cleanup;
1405         }
1406 
1407         ret = testCase.openCamera(cameraId);
1408         if (ret != ACAMERA_OK) {
1409             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1410             goto cleanup;
1411         }
1412 
1413         usleep(100000); // sleep to give some time for callbacks to happen
1414 
1415         if (testCase.isCameraAvailable(cameraId)) {
1416             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1417             goto cleanup;
1418         }
1419 
1420         ret = testCase.closeCamera();
1421         if (ret != ACAMERA_OK) {
1422             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
1423             goto cleanup;
1424         }
1425 
1426         usleep(100000); // sleep to give some time for callbacks to happen
1427 
1428         if (!testCase.isCameraAvailable(cameraId)) {
1429             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1430             goto cleanup;
1431         }
1432     }
1433 
1434     ret = testCase.deInit();
1435     if (ret != ACAMERA_OK) {
1436         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1437         goto cleanup;
1438     }
1439 
1440     pass = true;
1441 cleanup:
1442     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1443     if (!pass) {
1444         throwAssertionError(env, errorString);
1445     }
1446     return pass;
1447 }
1448 
1449 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass)1450 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1451 testCameraDeviceCreateCaptureRequestNative(
1452         JNIEnv* env, jclass /*clazz*/) {
1453     ALOGV("%s", __FUNCTION__);
1454     bool pass = false;
1455     ACameraManager* mgr = ACameraManager_create();
1456     ACameraIdList* cameraIdList = nullptr;
1457     ACameraDevice* device = nullptr;
1458     ACaptureRequest* request = nullptr;
1459     ACameraMetadata* chars = nullptr;
1460     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1461 
1462     int numCameras = cameraIdList->numCameras;
1463     for (int i = 0; i < numCameras; i++) {
1464         CameraDeviceListener deviceListener;
1465         const char* cameraId = cameraIdList->cameraIds[i];
1466         ACameraDevice_StateCallbacks deviceCb {
1467             &deviceListener,
1468             CameraDeviceListener::onDisconnected,
1469             CameraDeviceListener::onError
1470         };
1471         ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
1472         if (ret != ACAMERA_OK) {
1473             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1474             goto cleanup;
1475         }
1476 
1477         ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
1478         if (ret != ACAMERA_OK || chars == nullptr) {
1479             LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
1480                     cameraId, ret, chars);
1481             goto cleanup;
1482         }
1483         StaticInfo staticInfo(chars);
1484 
1485         for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
1486             ACameraDevice_request_template templateId =
1487                     static_cast<ACameraDevice_request_template>(t);
1488             ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
1489             if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
1490                 // template not supported. skip
1491                 continue;
1492             }
1493 
1494             if (ret != ACAMERA_OK) {
1495                 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
1496                 goto cleanup;
1497             }
1498 
1499             int32_t numTags = 0;
1500             const uint32_t* tags = nullptr;
1501             ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
1502             if (ret != ACAMERA_OK) {
1503                 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
1504                 goto cleanup;
1505             }
1506 
1507             for (int tid = 0; tid < numTags; tid++) {
1508                 uint32_t tagId = tags[tid];
1509                 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
1510                 uint32_t sectionId = tagId >> 16;
1511                 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
1512                     LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
1513                     goto cleanup;
1514                 }
1515             }
1516 
1517             void* context = nullptr;
1518             ret = ACaptureRequest_getUserContext(request, &context);
1519             if (ret != ACAMERA_OK) {
1520                 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
1521                 goto cleanup;
1522             }
1523             if (context != nullptr) {
1524                 LOG_ERROR(errorString, "Capture request context is not null: %p", context);
1525                 goto cleanup;
1526             }
1527 
1528             intptr_t magic_num = 0xBEEF;
1529             ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
1530             if (ret != ACAMERA_OK) {
1531                 LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
1532                 goto cleanup;
1533             }
1534 
1535             ret = ACaptureRequest_getUserContext(request, &context);
1536             if (ret != ACAMERA_OK) {
1537                 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
1538                 goto cleanup;
1539             }
1540             if (context != (void*) magic_num) {
1541                 LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
1542                 goto cleanup;
1543             }
1544 
1545             // try get/set capture request fields
1546             ACameraMetadata_const_entry entry;
1547             ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
1548             if (ret != ACAMERA_OK) {
1549                 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
1550                 goto cleanup;
1551             }
1552 
1553             if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
1554                     entry.count != 1) {
1555                 LOG_ERROR(errorString,
1556                         "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
1557                         "count %d (expect %d)",
1558                         entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
1559                         entry.count, 1);
1560                 goto cleanup;
1561             }
1562             if (t == TEMPLATE_MANUAL) {
1563                 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
1564                     LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
1565                             entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
1566                     goto cleanup;
1567                 }
1568                 // try set AE_MODE_ON
1569                 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
1570                 ret = ACaptureRequest_setEntry_u8(
1571                         request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
1572                 if (ret != ACAMERA_OK) {
1573                     LOG_ERROR(errorString,
1574                             "Error: Camera %s template %d: update AE mode key fail. ret %d",
1575                             cameraId, t, ret);
1576                     goto cleanup;
1577                 }
1578                 ret = ACaptureRequest_getConstEntry(
1579                         request, ACAMERA_CONTROL_AE_MODE, &entry);
1580                 if (ret != ACAMERA_OK) {
1581                     LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
1582                     goto cleanup;
1583                 }
1584                 if (entry.data.u8[0] != aeMode) {
1585                     LOG_ERROR(errorString,
1586                             "Error: AE mode key is not updated. expect %d but get %d",
1587                             aeMode, entry.data.u8[0]);
1588                     goto cleanup;
1589                 }
1590             } else {
1591                 if (staticInfo.isColorOutputSupported()) {
1592                     if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
1593                         LOG_ERROR(errorString,
1594                                 "Error: Template %d has wrong AE mode %d (expect %d)",
1595                                 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
1596                         goto cleanup;
1597                     }
1598                     // try set AE_MODE_OFF
1599                     if (staticInfo.isCapabilitySupported(
1600                             ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
1601                         uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
1602                         ret = ACaptureRequest_setEntry_u8(
1603                                 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
1604                         if (ret != ACAMERA_OK) {
1605                             LOG_ERROR(errorString,
1606                                     "Error: Camera %s template %d: update AE mode key fail. ret %d",
1607                                     cameraId, t, ret);
1608                             goto cleanup;
1609                         }
1610                         ret = ACaptureRequest_getConstEntry(
1611                                 request, ACAMERA_CONTROL_AE_MODE, &entry);
1612                         if (ret != ACAMERA_OK) {
1613                             LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
1614                             goto cleanup;
1615                         }
1616                         if (entry.data.u8[0] != aeMode) {
1617                             LOG_ERROR(errorString,
1618                                     "Error: AE mode key is not updated. expect %d but get %d",
1619                                     aeMode, entry.data.u8[0]);
1620                             goto cleanup;
1621                         }
1622                     }
1623                 }
1624             }
1625             ACaptureRequest_free(request);
1626             request = nullptr;
1627         }
1628 
1629         ACameraMetadata_free(chars);
1630         chars = nullptr;
1631         ACameraDevice_close(device);
1632         device = nullptr;
1633     }
1634 
1635     pass = true;
1636 cleanup:
1637     if (cameraIdList) {
1638         ACameraManager_deleteCameraIdList(cameraIdList);
1639     }
1640     if (request) {
1641         ACaptureRequest_free(request);
1642     }
1643     if (chars) {
1644         ACameraMetadata_free(chars);
1645     }
1646     if (device) {
1647         ACameraDevice_close(device);
1648     }
1649     if (mgr) {
1650         ACameraManager_delete(mgr);
1651     }
1652     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1653     if (!pass) {
1654         throwAssertionError(env, errorString);
1655     }
1656     return pass;
1657 }
1658 
1659 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface)1660 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1661 testCameraDeviceSessionOpenAndCloseNative(
1662         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
1663     ALOGV("%s", __FUNCTION__);
1664     int numCameras = 0;
1665     bool pass = false;
1666     PreviewTestCase testCase;
1667 
1668     camera_status_t ret = testCase.initWithErrorLog();
1669     if (ret != ACAMERA_OK) {
1670         // Don't log error here. testcase did it
1671         goto cleanup;
1672     }
1673 
1674     numCameras = testCase.getNumCameras();
1675     if (numCameras < 0) {
1676         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1677         goto cleanup;
1678     }
1679 
1680     for (int i = 0; i < numCameras; i++) {
1681         const char* cameraId = testCase.getCameraId(i);
1682         if (cameraId == nullptr) {
1683             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1684             goto cleanup;
1685         }
1686 
1687         ret = testCase.openCamera(cameraId);
1688         if (ret != ACAMERA_OK) {
1689             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1690             goto cleanup;
1691         }
1692 
1693         usleep(100000); // sleep to give some time for callbacks to happen
1694 
1695         if (testCase.isCameraAvailable(cameraId)) {
1696             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1697             goto cleanup;
1698         }
1699 
1700         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
1701         if (previewAnw == nullptr) {
1702             LOG_ERROR(errorString, "Null ANW from preview surface!");
1703             goto cleanup;
1704         }
1705 
1706         CaptureSessionListener* sessionListener = testCase.getSessionListener();
1707         if (sessionListener == nullptr) {
1708             LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
1709             goto cleanup;
1710         }
1711 
1712         // Try open/close session multiple times
1713         for (int j = 0; j < 5; j++) {
1714             ret = testCase.createCaptureSessionWithLog();
1715             if (ret != ACAMERA_OK) {
1716                 // Don't log error here. testcase did it
1717                 goto cleanup;
1718             }
1719 
1720             usleep(100000); // sleep to give some time for callbacks to happen
1721 
1722             if (!sessionListener->isIdle()) {
1723                 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
1724                         cameraId);
1725                 goto cleanup;
1726             }
1727 
1728             testCase.closeSession();
1729 
1730             usleep(100000); // sleep to give some time for callbacks to happen
1731             if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
1732                 LOG_ERROR(errorString,
1733                         "Session for camera %s close error. isClosde %d close count %d",
1734                         cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
1735                 goto cleanup;
1736             }
1737             sessionListener->reset();
1738         }
1739 
1740         // Try open/close really fast
1741         ret = testCase.createCaptureSessionWithLog();
1742         if (ret != ACAMERA_OK) {
1743             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
1744                     cameraId, ret);
1745             goto cleanup;
1746         }
1747         testCase.closeSession();
1748         usleep(100000); // sleep to give some time for callbacks to happen
1749         if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
1750             LOG_ERROR(errorString,
1751                     "Session for camera %s close error. isClosde %d close count %d",
1752                     cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
1753             goto cleanup;
1754         }
1755 
1756         ret = testCase.resetWithErrorLog();
1757         if (ret != ACAMERA_OK) {
1758             // Don't log error here. testcase did it
1759             goto cleanup;
1760         }
1761 
1762         usleep(100000); // sleep to give some time for callbacks to happen
1763 
1764         if (!testCase.isCameraAvailable(cameraId)) {
1765             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1766             goto cleanup;
1767         }
1768     }
1769 
1770     ret = testCase.deInit();
1771     if (ret != ACAMERA_OK) {
1772         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1773         goto cleanup;
1774     }
1775 
1776     pass = true;
1777 cleanup:
1778     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1779     if (!pass) {
1780         throwAssertionError(env, errorString);
1781     }
1782     return pass;
1783 }
1784 
1785 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSharedOutputUpdate(JNIEnv * env,jclass,jobject jPreviewSurface,jobject jSharedSurface)1786 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1787 testCameraDeviceSharedOutputUpdate(
1788         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface) {
1789     ALOGV("%s", __FUNCTION__);
1790     int numCameras = 0;
1791     bool pass = false;
1792     PreviewTestCase testCase;
1793     int sequenceId = -1;
1794     int64_t lastFrameNumber = 0;
1795     bool frameArrived = false;
1796     ANativeWindow* previewAnw = nullptr;
1797     ANativeWindow* sharedAnw = ANativeWindow_fromSurface(env, jSharedSurface);
1798     ACaptureRequest* updatedRequest = nullptr;
1799     ACameraOutputTarget* reqPreviewOutput = nullptr;
1800     ACameraOutputTarget* reqSharedOutput = nullptr;
1801     ACaptureSessionOutput *previewOutput = nullptr;
1802     uint32_t timeoutSec = 1;
1803     uint32_t runPreviewSec = 2;
1804 
1805     camera_status_t ret = testCase.initWithErrorLog();
1806     if (ret != ACAMERA_OK) {
1807         // Don't log error here. testcase did it
1808         goto cleanup;
1809     }
1810 
1811     numCameras = testCase.getNumCameras();
1812     if (numCameras < 0) {
1813         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1814         goto cleanup;
1815     }
1816 
1817     for (int i = 0; i < numCameras; i++) {
1818         const char* cameraId = testCase.getCameraId(i);
1819         if (cameraId == nullptr) {
1820             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1821             goto cleanup;
1822         }
1823 
1824         ret = testCase.openCamera(cameraId);
1825         if (ret != ACAMERA_OK) {
1826             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1827             goto cleanup;
1828         }
1829 
1830         usleep(100000); // sleep to give some time for callbacks to happen
1831 
1832         if (testCase.isCameraAvailable(cameraId)) {
1833             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1834             goto cleanup;
1835         }
1836 
1837         previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
1838         if (previewAnw == nullptr) {
1839             LOG_ERROR(errorString, "Null ANW from preview surface!");
1840             goto cleanup;
1841         }
1842 
1843         ret = testCase.createCaptureSessionWithLog(true);
1844         if (ret != ACAMERA_OK) {
1845             // Don't log error here. testcase did it
1846             goto cleanup;
1847         }
1848 
1849         ret = testCase.createRequestsWithErrorLog();
1850         if (ret != ACAMERA_OK) {
1851             // Don't log error here. testcase did it
1852             goto cleanup;
1853         }
1854 
1855         ret = testCase.startPreview();
1856         if (ret != ACAMERA_OK) {
1857             LOG_ERROR(errorString, "Start preview failed!");
1858             goto cleanup;
1859         }
1860 
1861         sleep(runPreviewSec);
1862 
1863         previewOutput = testCase.getPreviewOutput();
1864         //Try some bad input
1865         ret = ACaptureSessionSharedOutput_add(previewOutput, previewAnw);
1866         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
1867             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add should return invalid "
1868                     "parameter! %d", ret);
1869             goto cleanup;
1870         }
1871 
1872         ret = ACaptureSessionSharedOutput_remove(previewOutput, previewAnw);
1873         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
1874             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove should return invalid "
1875                     "parameter! %d", ret);
1876             goto cleanup;
1877         }
1878 
1879         //Now try with valid input
1880         ret = ACaptureSessionSharedOutput_add(previewOutput, sharedAnw);
1881         if (ret != ACAMERA_OK) {
1882             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add failed!")
1883             goto cleanup;
1884         }
1885 
1886         ret = testCase.updateOutput(env, previewOutput);
1887         if (ret != ACAMERA_OK) {
1888             LOG_ERROR(errorString, "Failed to update output configuration!")
1889             goto cleanup;
1890         }
1891 
1892         ret = ACameraDevice_createCaptureRequest(
1893                 testCase.getCameraDevice(), TEMPLATE_PREVIEW, &updatedRequest);
1894         if (ret != ACAMERA_OK) {
1895             LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
1896                     cameraId, ret);
1897             goto cleanup;
1898         }
1899 
1900         ret = ACameraOutputTarget_create(previewAnw, &reqPreviewOutput);
1901         if (ret != ACAMERA_OK) {
1902             LOG_ERROR(errorString,
1903                     "Camera %s create request preview output target failed. ret %d",
1904                     cameraId, ret);
1905             goto cleanup;
1906         }
1907 
1908         ret = ACaptureRequest_addTarget(updatedRequest, reqPreviewOutput);
1909         if (ret != ACAMERA_OK) {
1910             LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
1911                     cameraId, ret);
1912             goto cleanup;
1913         }
1914 
1915         ret = ACameraOutputTarget_create(sharedAnw, &reqSharedOutput);
1916         if (ret != ACAMERA_OK) {
1917             LOG_ERROR(errorString,
1918                     "Camera %s create request preview output target failed. ret %d",
1919                     cameraId, ret);
1920             goto cleanup;
1921         }
1922 
1923         ret = ACaptureRequest_addTarget(updatedRequest, reqSharedOutput);
1924         if (ret != ACAMERA_OK) {
1925             LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
1926                     cameraId, ret);
1927             goto cleanup;
1928         }
1929 
1930         ret = testCase.updateRepeatingRequest(updatedRequest, &sequenceId);
1931         if (ret != ACAMERA_OK) {
1932             LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
1933                     cameraId, ret);
1934             goto cleanup;
1935         }
1936 
1937         sleep(runPreviewSec);
1938 
1939         ret = ACaptureSessionSharedOutput_remove(previewOutput, sharedAnw);
1940         if (ret != ACAMERA_OK) {
1941             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove failed!");
1942             goto cleanup;
1943         }
1944 
1945         //Try removing shared output which still has pending camera requests
1946         ret = testCase.updateOutput(env, previewOutput);
1947         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
1948             LOG_ERROR(errorString, "updateOutput should fail!");
1949             goto cleanup;
1950         }
1951 
1952         //Remove the shared output correctly by updating the repeating request
1953         //first
1954         ret = ACaptureRequest_removeTarget(updatedRequest, reqSharedOutput);
1955         if (ret != ACAMERA_OK) {
1956             LOG_ERROR(errorString, "Camera %s remove target output failed. ret %d",
1957                     cameraId, ret);
1958             goto cleanup;
1959         }
1960 
1961         ret = testCase.updateRepeatingRequest(updatedRequest);
1962         if (ret != ACAMERA_OK) {
1963             LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
1964                     cameraId, ret);
1965             goto cleanup;
1966         }
1967 
1968         //Then wait for all old requests to flush
1969         lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
1970         if (lastFrameNumber < 0) {
1971             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
1972                     cameraId);
1973             goto cleanup;
1974         }
1975 
1976         frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
1977         if (!frameArrived) {
1978             LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
1979                     cameraId);
1980             goto cleanup;
1981         }
1982 
1983         ret = testCase.updateOutput(env, previewOutput);
1984         if (ret != ACAMERA_OK) {
1985             LOG_ERROR(errorString, "updateOutput failed!");
1986             goto cleanup;
1987         }
1988 
1989         sleep(runPreviewSec);
1990 
1991         ret = testCase.resetWithErrorLog();
1992         if (ret != ACAMERA_OK) {
1993             // Don't log error here. testcase did it
1994             goto cleanup;
1995         }
1996 
1997         usleep(100000); // sleep to give some time for callbacks to happen
1998 
1999         if (!testCase.isCameraAvailable(cameraId)) {
2000             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2001             goto cleanup;
2002         }
2003     }
2004 
2005     ret = testCase.deInit();
2006     if (ret != ACAMERA_OK) {
2007         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2008         goto cleanup;
2009     }
2010 
2011     pass = true;
2012 
2013 cleanup:
2014 
2015     if (updatedRequest != nullptr) {
2016         ACaptureRequest_free(updatedRequest);
2017         updatedRequest = nullptr;
2018     }
2019 
2020     if (reqPreviewOutput != nullptr) {
2021         ACameraOutputTarget_free(reqPreviewOutput);
2022         reqPreviewOutput = nullptr;
2023     }
2024 
2025     if (reqSharedOutput != nullptr) {
2026         ACameraOutputTarget_free(reqSharedOutput);
2027         reqSharedOutput = nullptr;
2028     }
2029 
2030     if (sharedAnw) {
2031         ANativeWindow_release(sharedAnw);
2032         sharedAnw = nullptr;
2033     }
2034 
2035     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2036     if (!pass) {
2037         throwAssertionError(env, errorString);
2038     }
2039     return pass;
2040 }
2041 
2042 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass,jobject jPreviewSurface)2043 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2044 testCameraDeviceSimplePreviewNative(
2045         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
2046     ALOGV("%s", __FUNCTION__);
2047     int numCameras = 0;
2048     bool pass = false;
2049     PreviewTestCase testCase;
2050 
2051     camera_status_t ret = testCase.initWithErrorLog();
2052     if (ret != ACAMERA_OK) {
2053         // Don't log error here. testcase did it
2054         goto cleanup;
2055     }
2056 
2057     numCameras = testCase.getNumCameras();
2058     if (numCameras < 0) {
2059         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2060         goto cleanup;
2061     }
2062 
2063     for (int i = 0; i < numCameras; i++) {
2064         const char* cameraId = testCase.getCameraId(i);
2065         if (cameraId == nullptr) {
2066             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2067             goto cleanup;
2068         }
2069 
2070         ret = testCase.openCamera(cameraId);
2071         if (ret != ACAMERA_OK) {
2072             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2073             goto cleanup;
2074         }
2075 
2076         usleep(100000); // sleep to give some time for callbacks to happen
2077 
2078         if (testCase.isCameraAvailable(cameraId)) {
2079             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2080             goto cleanup;
2081         }
2082 
2083         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2084         if (previewAnw == nullptr) {
2085             LOG_ERROR(errorString, "Null ANW from preview surface!");
2086             goto cleanup;
2087         }
2088 
2089         ret = testCase.createCaptureSessionWithLog();
2090         if (ret != ACAMERA_OK) {
2091             // Don't log error here. testcase did it
2092             goto cleanup;
2093         }
2094 
2095         ret = testCase.createRequestsWithErrorLog();
2096         if (ret != ACAMERA_OK) {
2097             // Don't log error here. testcase did it
2098             goto cleanup;
2099         }
2100 
2101         ret = testCase.startPreview();
2102         if (ret != ACAMERA_OK) {
2103             LOG_ERROR(errorString, "Start preview failed!");
2104             goto cleanup;
2105         }
2106 
2107         sleep(3);
2108 
2109         ret = testCase.resetWithErrorLog();
2110         if (ret != ACAMERA_OK) {
2111             // Don't log error here. testcase did it
2112             goto cleanup;
2113         }
2114 
2115         usleep(100000); // sleep to give some time for callbacks to happen
2116 
2117         if (!testCase.isCameraAvailable(cameraId)) {
2118             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2119             goto cleanup;
2120         }
2121     }
2122 
2123     ret = testCase.deInit();
2124     if (ret != ACAMERA_OK) {
2125         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2126         goto cleanup;
2127     }
2128 
2129     pass = true;
2130 cleanup:
2131     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2132     if (!pass) {
2133         throwAssertionError(env, errorString);
2134     }
2135     return pass;
2136 }
2137 
2138 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDevicePreviewWithSessionParametersNative(JNIEnv * env,jclass,jobject jPreviewSurface)2139 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2140 testCameraDevicePreviewWithSessionParametersNative(
2141         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
2142     ALOGV("%s", __FUNCTION__);
2143     int numCameras = 0;
2144     bool pass = false;
2145     ACameraManager* mgr = ACameraManager_create();
2146     ACameraMetadata* chars = nullptr;
2147     PreviewTestCase testCase;
2148 
2149     camera_status_t ret = testCase.initWithErrorLog();
2150     if (ret != ACAMERA_OK) {
2151         // Don't log error here. testcase did it
2152         goto cleanup;
2153     }
2154 
2155     numCameras = testCase.getNumCameras();
2156     if (numCameras < 0) {
2157         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2158         goto cleanup;
2159     }
2160 
2161     for (int i = 0; i < numCameras; i++) {
2162         const char* cameraId = testCase.getCameraId(i);
2163         if (cameraId == nullptr) {
2164             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2165             goto cleanup;
2166         }
2167 
2168         ret = ACameraManager_getCameraCharacteristics(
2169                 mgr, cameraId, &chars);
2170         if (ret != ACAMERA_OK) {
2171             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2172             goto cleanup;
2173         }
2174 
2175         ACameraMetadata_const_entry sessionParamKeys{};
2176         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS,
2177                 &sessionParamKeys);
2178         if ((ret != ACAMERA_OK) || (sessionParamKeys.count == 0)) {
2179             ACameraMetadata_free(chars);
2180             chars = nullptr;
2181             continue;
2182         }
2183 
2184         ret = testCase.openCamera(cameraId);
2185         if (ret != ACAMERA_OK) {
2186             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2187             goto cleanup;
2188         }
2189 
2190         usleep(100000); // sleep to give some time for callbacks to happen
2191 
2192         if (testCase.isCameraAvailable(cameraId)) {
2193             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2194             goto cleanup;
2195         }
2196 
2197         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2198         if (previewAnw == nullptr) {
2199             LOG_ERROR(errorString, "Null ANW from preview surface!");
2200             goto cleanup;
2201         }
2202 
2203         ret = testCase.createRequestsWithErrorLog();
2204         if (ret != ACAMERA_OK) {
2205             // Don't log error here. testcase did it
2206             goto cleanup;
2207         }
2208 
2209         ACaptureRequest *previewRequest = nullptr;
2210         ret = testCase.getPreviewRequest(&previewRequest);
2211         if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
2212             LOG_ERROR(errorString, "Preview request query failed!");
2213             goto cleanup;
2214         }
2215 
2216         ret = testCase.createCaptureSessionWithLog(/*isPreviewShared*/ false, previewRequest);
2217         if (ret != ACAMERA_OK) {
2218             // Don't log error here. testcase did it
2219             goto cleanup;
2220         }
2221 
2222         ret = testCase.startPreview();
2223         if (ret != ACAMERA_OK) {
2224             LOG_ERROR(errorString, "Start preview failed!");
2225             goto cleanup;
2226         }
2227 
2228         sleep(3);
2229 
2230         ret = testCase.resetWithErrorLog();
2231         if (ret != ACAMERA_OK) {
2232             // Don't log error here. testcase did it
2233             goto cleanup;
2234         }
2235 
2236         usleep(100000); // sleep to give some time for callbacks to happen
2237 
2238         if (!testCase.isCameraAvailable(cameraId)) {
2239             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2240             goto cleanup;
2241         }
2242 
2243         ACameraMetadata_free(chars);
2244         chars = nullptr;
2245     }
2246 
2247     ret = testCase.deInit();
2248     if (ret != ACAMERA_OK) {
2249         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2250         goto cleanup;
2251     }
2252 
2253     pass = true;
2254 cleanup:
2255     if (chars) {
2256         ACameraMetadata_free(chars);
2257     }
2258     ACameraManager_delete(mgr);
2259     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2260     if (!pass) {
2261         throwAssertionError(env, errorString);
2262     }
2263     return pass;
2264 }
2265 
nativeImageReaderTestBase(JNIEnv * env,jstring jOutPath,AImageReader_ImageCallback cb)2266 bool nativeImageReaderTestBase(
2267         JNIEnv* env, jstring jOutPath, AImageReader_ImageCallback cb) {
2268     const int NUM_TEST_IMAGES = 10;
2269     const int TEST_WIDTH  = 640;
2270     const int TEST_HEIGHT = 480;
2271     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
2272     int numCameras = 0;
2273     bool pass = false;
2274     PreviewTestCase testCase;
2275 
2276     const char* outPath = (jOutPath == nullptr) ? nullptr :
2277             env->GetStringUTFChars(jOutPath, nullptr);
2278     if (outPath != nullptr) {
2279         ALOGI("%s: out path is %s", __FUNCTION__, outPath);
2280     }
2281 
2282     camera_status_t ret = testCase.initWithErrorLog();
2283     if (ret != ACAMERA_OK) {
2284         // Don't log error here. testcase did it
2285         goto cleanup;
2286     }
2287 
2288     numCameras = testCase.getNumCameras();
2289     if (numCameras < 0) {
2290         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2291         goto cleanup;
2292     }
2293 
2294     for (int i = 0; i < numCameras; i++) {
2295         const char* cameraId = testCase.getCameraId(i);
2296         if (cameraId == nullptr) {
2297             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2298             goto cleanup;
2299         }
2300 
2301         ret = testCase.openCamera(cameraId);
2302         if (ret != ACAMERA_OK) {
2303             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2304             goto cleanup;
2305         }
2306 
2307         usleep(100000); // sleep to give some time for callbacks to happen
2308 
2309         if (testCase.isCameraAvailable(cameraId)) {
2310             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2311             goto cleanup;
2312         }
2313 
2314         ImageReaderListener readerListener;
2315         AImageReader_ImageListener readerCb { &readerListener, cb };
2316         readerListener.setDumpFilePathBase(outPath);
2317 
2318         mediaRet = testCase.initImageReaderWithErrorLog(
2319                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
2320                 &readerCb);
2321         if (mediaRet != AMEDIA_OK) {
2322             // Don't log error here. testcase did it
2323             goto cleanup;
2324         }
2325 
2326         ret = testCase.createCaptureSessionWithLog();
2327         if (ret != ACAMERA_OK) {
2328             // Don't log error here. testcase did it
2329             goto cleanup;
2330         }
2331 
2332         ret = testCase.createRequestsWithErrorLog();
2333         if (ret != ACAMERA_OK) {
2334             // Don't log error here. testcase did it
2335             goto cleanup;
2336         }
2337 
2338         CaptureResultListener resultListener;
2339         ACameraCaptureSession_captureCallbacks resultCb {
2340             &resultListener,
2341             CaptureResultListener::onCaptureStart,
2342             CaptureResultListener::onCaptureProgressed,
2343             CaptureResultListener::onCaptureCompleted,
2344             CaptureResultListener::onCaptureFailed,
2345             CaptureResultListener::onCaptureSequenceCompleted,
2346             CaptureResultListener::onCaptureSequenceAborted,
2347             CaptureResultListener::onCaptureBufferLost
2348         };
2349         resultListener.setRequestSave(true);
2350         ACaptureRequest* requestTemplate = nullptr;
2351         ret = testCase.getStillRequest(&requestTemplate);
2352         if (ret != ACAMERA_OK || requestTemplate == nullptr) {
2353             // Don't log error here. testcase did it
2354             goto cleanup;
2355         }
2356 
2357         // Do some still capture
2358         int lastSeqId = -1;
2359         for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
2360             ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
2361             ACaptureRequest_setUserContext(req, (void*) capture);
2362             int seqId;
2363             ret = testCase.capture(req, &resultCb, &seqId);
2364             if (ret != ACAMERA_OK) {
2365                 LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
2366                         cameraId, capture, ret);
2367                 goto cleanup;
2368             }
2369             if (capture == NUM_TEST_IMAGES - 1) {
2370                 lastSeqId = seqId;
2371             }
2372             ACaptureRequest_free(req);
2373         }
2374 
2375         // wait until last sequence complete
2376         resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 3);
2377 
2378         std::vector<ACaptureRequest*> completedRequests;
2379         resultListener.getCompletedRequests(&completedRequests);
2380 
2381         if (completedRequests.size() != NUM_TEST_IMAGES) {
2382             LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
2383                     cameraId, NUM_TEST_IMAGES, completedRequests.size());
2384             goto cleanup;
2385         }
2386 
2387         for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
2388             intptr_t userContext = -1;
2389             ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
2390             if (ret != ACAMERA_OK) {
2391                 LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
2392                 goto cleanup;
2393             }
2394 
2395             if (userContext != i) {
2396                 LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
2397                         "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
2398                 goto cleanup;
2399             }
2400         }
2401 
2402         // wait until all capture finished
2403         for (int i = 0; i < 50; i++) {
2404             usleep(100000); // sleep 100ms
2405             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
2406                 ALOGI("Session take ~%d ms to capture %d images",
2407                         i*100, NUM_TEST_IMAGES);
2408                 break;
2409             }
2410         }
2411 
2412         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
2413             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
2414                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
2415             goto cleanup;
2416         }
2417 
2418         ret = testCase.resetWithErrorLog();
2419         if (ret != ACAMERA_OK) {
2420             // Don't log error here. testcase did it
2421             goto cleanup;
2422         }
2423 
2424         usleep(100000); // sleep to give some time for callbacks to happen
2425 
2426         if (!testCase.isCameraAvailable(cameraId)) {
2427             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2428             goto cleanup;
2429         }
2430     }
2431 
2432     ret = testCase.deInit();
2433     if (ret != ACAMERA_OK) {
2434         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2435         goto cleanup;
2436     }
2437 
2438     pass = true;
2439 
2440 cleanup:
2441     if (outPath != nullptr) {
2442         env->ReleaseStringUTFChars(jOutPath, outPath);
2443     }
2444     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2445     if (!pass) {
2446         throwAssertionError(env, errorString);
2447     }
2448     return pass;
2449 }
2450 
2451 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath)2452 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
2453 testJpegNative(
2454         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
2455     ALOGV("%s", __FUNCTION__);
2456     return nativeImageReaderTestBase(env, jOutPath, ImageReaderListener::validateImageCb);
2457 }
2458 
2459 
2460 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testImageReaderCloseAcquiredImagesNative(JNIEnv * env,jclass)2461 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
2462 testImageReaderCloseAcquiredImagesNative(
2463         JNIEnv* env, jclass /*clazz*/) {
2464     ALOGV("%s", __FUNCTION__);
2465     return nativeImageReaderTestBase(env, nullptr, ImageReaderListener::acquireImageCb);
2466 }
2467 
2468 
2469 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface)2470 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
2471 testStillCaptureNative(
2472         JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
2473     ALOGV("%s", __FUNCTION__);
2474     const int NUM_TEST_IMAGES = 10;
2475     const int TEST_WIDTH  = 640;
2476     const int TEST_HEIGHT = 480;
2477     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
2478     int numCameras = 0;
2479     bool pass = false;
2480     PreviewTestCase testCase;
2481 
2482     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
2483     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
2484 
2485     camera_status_t ret = testCase.initWithErrorLog();
2486     if (ret != ACAMERA_OK) {
2487         // Don't log error here. testcase did it
2488         goto cleanup;
2489     }
2490 
2491     numCameras = testCase.getNumCameras();
2492     if (numCameras < 0) {
2493         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2494         goto cleanup;
2495     }
2496 
2497     for (int i = 0; i < numCameras; i++) {
2498         const char* cameraId = testCase.getCameraId(i);
2499         if (cameraId == nullptr) {
2500             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2501             goto cleanup;
2502         }
2503 
2504         ret = testCase.openCamera(cameraId);
2505         if (ret != ACAMERA_OK) {
2506             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2507             goto cleanup;
2508         }
2509 
2510         usleep(100000); // sleep to give some time for callbacks to happen
2511 
2512         if (testCase.isCameraAvailable(cameraId)) {
2513             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2514             goto cleanup;
2515         }
2516 
2517         ImageReaderListener readerListener;
2518         AImageReader_ImageListener readerCb {
2519             &readerListener,
2520             ImageReaderListener::validateImageCb
2521         };
2522         readerListener.setDumpFilePathBase(outPath);
2523         mediaRet = testCase.initImageReaderWithErrorLog(
2524                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
2525                 &readerCb);
2526         if (mediaRet != AMEDIA_OK) {
2527             // Don't log error here. testcase did it
2528             goto cleanup;
2529         }
2530 
2531         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2532         if (previewAnw == nullptr) {
2533             LOG_ERROR(errorString, "Null ANW from preview surface!");
2534             goto cleanup;
2535         }
2536 
2537         ret = testCase.createCaptureSessionWithLog();
2538         if (ret != ACAMERA_OK) {
2539             // Don't log error here. testcase did it
2540             goto cleanup;
2541         }
2542 
2543         ret = testCase.createRequestsWithErrorLog();
2544         if (ret != ACAMERA_OK) {
2545             // Don't log error here. testcase did it
2546             goto cleanup;
2547         }
2548 
2549         ret = testCase.startPreview();
2550         if (ret != ACAMERA_OK) {
2551             LOG_ERROR(errorString, "Start preview failed!");
2552             goto cleanup;
2553         }
2554 
2555         // Let preview run some time
2556         sleep(3);
2557 
2558         // Do some still capture
2559         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
2560             ret = testCase.takePicture();
2561             if (ret != ACAMERA_OK) {
2562                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
2563                         cameraId, capture, ret);
2564                 goto cleanup;
2565             }
2566         }
2567 
2568         // wait until all capture finished
2569         for (int i = 0; i < 50; i++) {
2570             usleep(100000); // sleep 100ms
2571             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
2572                 ALOGI("Session take ~%d ms to capture %d images",
2573                         i*100, NUM_TEST_IMAGES);
2574                 break;
2575             }
2576         }
2577 
2578         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
2579             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
2580                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
2581             goto cleanup;
2582         }
2583 
2584         ret = testCase.resetWithErrorLog();
2585         if (ret != ACAMERA_OK) {
2586             // Don't log error here. testcase did it
2587             goto cleanup;
2588         }
2589 
2590         usleep(100000); // sleep to give some time for callbacks to happen
2591 
2592         if (!testCase.isCameraAvailable(cameraId)) {
2593             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2594             goto cleanup;
2595         }
2596     }
2597 
2598     ret = testCase.deInit();
2599     if (ret != ACAMERA_OK) {
2600         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2601         goto cleanup;
2602     }
2603 
2604     pass = true;
2605 cleanup:
2606     env->ReleaseStringUTFChars(jOutPath, outPath);
2607     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2608     if (!pass) {
2609         throwAssertionError(env, errorString);
2610     }
2611     return pass;
2612 }
2613 
2614