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 #include <set>
33 
34 #include <android/native_window_jni.h>
35 
36 #include "camera/NdkCameraError.h"
37 #include "camera/NdkCameraManager.h"
38 #include "camera/NdkCameraDevice.h"
39 #include "camera/NdkCameraCaptureSession.h"
40 #include "media/NdkImage.h"
41 #include "media/NdkImageReader.h"
42 
43 #define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
44                             ALOGE("%s", buf);
45 
46 namespace {
47     const int MAX_ERROR_STRING_LEN = 512;
48     char errorString[MAX_ERROR_STRING_LEN];
49 }
50 
51 template <>
52 struct std::default_delete<ACameraMetadata> {
operator ()std::default_delete53     inline void operator()(ACameraMetadata* chars) const { ACameraMetadata_free(chars); }
54 };
55 
56 class CameraServiceListener {
57   public:
onAvailable(void * obj,const char * cameraId)58     static void onAvailable(void* obj, const char* cameraId) {
59         ALOGV("Camera %s onAvailable", cameraId);
60         if (obj == nullptr) {
61             return;
62         }
63         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
64         std::lock_guard<std::mutex> lock(thiz->mMutex);
65         thiz->mOnAvailableCount++;
66         thiz->mAvailableMap[cameraId] = true;
67         return;
68     }
69 
onUnavailable(void * obj,const char * cameraId)70     static void onUnavailable(void* obj, const char* cameraId) {
71         ALOGV("Camera %s onUnavailable", cameraId);
72         if (obj == nullptr) {
73             return;
74         }
75         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
76         std::lock_guard<std::mutex> lock(thiz->mMutex);
77         thiz->mOnUnavailableCount++;
78         thiz->mAvailableMap[cameraId] = false;
79         return;
80     }
81 
82 
onCameraAccessPrioritiesChanged(void * obj)83     static void onCameraAccessPrioritiesChanged(void* obj) {
84         ALOGV("onCameraAccessPrioritiesChanged");
85         if (obj == nullptr) {
86             return;
87         }
88         CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
89         std::lock_guard<std::mutex> lock(thiz->mMutex);
90         thiz->mOnCameraAccessPrioritiesChangedCount++;
91         return;
92     }
93 
resetCount()94     void resetCount() {
95         std::lock_guard<std::mutex> lock(mMutex);
96         mOnAvailableCount = 0;
97         mOnUnavailableCount = 0;
98         mOnCameraAccessPrioritiesChangedCount = 0;
99         return;
100     }
101 
getAvailableCount()102     int getAvailableCount() {
103         std::lock_guard<std::mutex> lock(mMutex);
104         return mOnAvailableCount;
105     }
106 
getUnavailableCount()107     int getUnavailableCount() {
108         std::lock_guard<std::mutex> lock(mMutex);
109         return mOnUnavailableCount;
110     }
111 
getCameraAccessPrioritiesChangedCount()112     int getCameraAccessPrioritiesChangedCount() {
113         std::lock_guard<std::mutex> lock(mMutex);
114         return mOnCameraAccessPrioritiesChangedCount;
115     }
116 
isAvailable(const char * cameraId)117     bool isAvailable(const char* cameraId) {
118         std::lock_guard<std::mutex> lock(mMutex);
119         if (mAvailableMap.count(cameraId) == 0) {
120             return false;
121         }
122         return mAvailableMap[cameraId];
123     }
124 
125   private:
126     std::mutex mMutex;
127     int mOnAvailableCount = 0;
128     int mOnUnavailableCount = 0;
129     int mOnCameraAccessPrioritiesChangedCount = 0;
130     std::map<std::string, bool> mAvailableMap;
131 };
132 
133 class CameraDeviceListener {
134   public:
onDisconnected(void * obj,ACameraDevice * device)135     static void onDisconnected(void* obj, ACameraDevice* device) {
136         ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
137         if (obj == nullptr) {
138             return;
139         }
140         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
141         std::lock_guard<std::mutex> lock(thiz->mMutex);
142         thiz->mOnDisconnect++;
143         return;
144     }
145 
onError(void * obj,ACameraDevice * device,int errorCode)146     static void onError(void* obj, ACameraDevice* device, int errorCode) {
147         ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
148         if (obj == nullptr) {
149             return;
150         }
151         CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
152         std::lock_guard<std::mutex> lock(thiz->mMutex);
153         thiz->mOnError++;
154         thiz->mLatestError = errorCode;
155         return;
156     }
157 
158   private:
159     std::mutex mMutex;
160     int mOnDisconnect = 0;
161     int mOnError = 0;
162     int mLatestError = 0;
163 };
164 
165 class CaptureSessionListener {
166 
167   public:
onClosed(void * obj,ACameraCaptureSession * session)168     static void onClosed(void* obj, ACameraCaptureSession *session) {
169         // TODO: might want an API to query cameraId even session is closed?
170         ALOGV("Session %p is closed!", session);
171         if (obj == nullptr) {
172             return;
173         }
174         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
175         std::lock_guard<std::mutex> lock(thiz->mMutex);
176         thiz->mIsClosed = true;
177         thiz->mOnClosed++; // Should never > 1
178     }
179 
onReady(void * obj,ACameraCaptureSession * session)180     static void onReady(void* obj, ACameraCaptureSession *session) {
181         ALOGV("%s", __FUNCTION__);
182         if (obj == nullptr) {
183             return;
184         }
185         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
186         std::lock_guard<std::mutex> lock(thiz->mMutex);
187         ACameraDevice* device = nullptr;
188         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
189         // There will be one onReady fired after session closed
190         if (ret != ACAMERA_OK && !thiz->mIsClosed) {
191             ALOGE("%s Getting camera device from session callback failed!",
192                     __FUNCTION__);
193             thiz->mInError = true;
194         }
195         ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
196         thiz->mIsIdle = true;
197         thiz->mOnReady++;
198     }
199 
onActive(void * obj,ACameraCaptureSession * session)200     static void onActive(void* obj, ACameraCaptureSession *session) {
201         ALOGV("%s", __FUNCTION__);
202         if (obj == nullptr) {
203             return;
204         }
205         CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
206         std::lock_guard<std::mutex> lock(thiz->mMutex);
207         ACameraDevice* device = nullptr;
208         camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
209         if (ret != ACAMERA_OK) {
210             ALOGE("%s Getting camera device from session callback failed!",
211                     __FUNCTION__);
212             thiz->mInError = true;
213         }
214         ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
215         thiz->mIsIdle = false;
216         thiz->mOnActive;
217     }
218 
isClosed()219     bool isClosed() {
220         std::lock_guard<std::mutex> lock(mMutex);
221         return mIsClosed;
222     }
223 
isIdle()224     bool isIdle() {
225         std::lock_guard<std::mutex> lock(mMutex);
226         return mIsIdle;
227     }
228 
isInError()229     bool isInError() {
230         std::lock_guard<std::mutex> lock(mMutex);
231         return mInError;
232     }
233 
onClosedCount()234     int onClosedCount()  {
235         std::lock_guard<std::mutex> lock(mMutex);
236         return mOnClosed;
237     }
238 
onReadyCount()239     int onReadyCount()  {
240         std::lock_guard<std::mutex> lock(mMutex);
241         return mOnReady;
242     }
243 
onActiveCount()244     int onActiveCount()  {
245         std::lock_guard<std::mutex> lock(mMutex);
246         return mOnActive;
247     }
248 
reset()249     void reset() {
250         std::lock_guard<std::mutex> lock(mMutex);
251         mIsClosed = false;
252         mIsIdle = true;
253         mInError = false;
254         mOnClosed = 0;
255         mOnReady = 0;
256         mOnActive = 0;
257     }
258 
259   private:
260     std::mutex mMutex;
261     bool mIsClosed = false;
262     bool mIsIdle = true;
263     bool mInError = false; // should always stay false
264     int mOnClosed = 0;
265     int mOnReady = 0;
266     int mOnActive = 0;
267 };
268 
269 class CaptureResultListener {
270   public:
~CaptureResultListener()271     ~CaptureResultListener() {
272         std::unique_lock<std::mutex> l(mMutex);
273         clearSavedRequestsLocked();
274         clearFailedFrameNumbersLocked();
275     }
276 
onCaptureStart(void *,ACameraCaptureSession *,const ACaptureRequest *,int64_t)277     static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
278             const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
279         //Not used for now
280     }
281 
onCaptureProgressed(void *,ACameraCaptureSession *,ACaptureRequest *,const ACameraMetadata *)282     static void onCaptureProgressed(void* /*obj*/, ACameraCaptureSession* /*session*/,
283             ACaptureRequest* /*request*/, const ACameraMetadata* /*result*/) {
284         //Not used for now
285     }
286 
onCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result)287     static void onCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
288             ACaptureRequest* request, const ACameraMetadata* result) {
289         ALOGV("%s", __FUNCTION__);
290         if ((obj == nullptr) || (result == nullptr)) {
291             return;
292         }
293         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
294         std::lock_guard<std::mutex> lock(thiz->mMutex);
295         ACameraMetadata_const_entry entry;
296         auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
297         if (ret != ACAMERA_OK) {
298             ALOGE("Error: Sync frame number missing from result!");
299             return;
300         }
301 
302         ACameraMetadata* copy = ACameraMetadata_copy(result);
303         ACameraMetadata_const_entry entryCopy;
304         ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
305         if (ret != ACAMERA_OK) {
306             ALOGE("Error: Sync frame number missing from result copy!");
307             return;
308         }
309 
310         if (entry.data.i64[0] != entryCopy.data.i64[0]) {
311             ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
312                     entry.data.i64[0], entryCopy.data.i64[0]);
313             return;
314         }
315         ACameraMetadata_free(copy);
316 
317         if (thiz->mSaveCompletedRequests) {
318             thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
319         }
320 
321         thiz->mLastCompletedFrameNumber = entry.data.i64[0];
322         thiz->mResultCondition.notify_one();
323     }
324 
onLogicalCameraCaptureCompleted(void * obj,ACameraCaptureSession *,ACaptureRequest * request,const ACameraMetadata * result,size_t physicalResultCount,const char ** physicalCameraIds,const ACameraMetadata ** physicalResults)325     static void onLogicalCameraCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
326             ACaptureRequest* request, const ACameraMetadata* result,
327             size_t physicalResultCount, const char** physicalCameraIds,
328             const ACameraMetadata** physicalResults) {
329         ALOGV("%s", __FUNCTION__);
330         if ((obj == nullptr) || (result == nullptr)) {
331             return;
332         }
333         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
334         std::lock_guard<std::mutex> lock(thiz->mMutex);
335         ACameraMetadata_const_entry entry;
336         auto ret = ACameraMetadata_getConstEntry(result, ACAMERA_SYNC_FRAME_NUMBER, &entry);
337         if (ret != ACAMERA_OK) {
338             ALOGE("Error: Sync frame number missing from result!");
339             return;
340         }
341 
342         ACameraMetadata* copy = ACameraMetadata_copy(result);
343         ACameraMetadata_const_entry entryCopy;
344         ret = ACameraMetadata_getConstEntry(copy, ACAMERA_SYNC_FRAME_NUMBER, &entryCopy);
345         if (ret != ACAMERA_OK) {
346             ALOGE("Error: Sync frame number missing from result copy!");
347             return;
348         }
349 
350         if (entry.data.i64[0] != entryCopy.data.i64[0]) {
351             ALOGE("Error: Sync frame number %" PRId64 " mismatch result copy %" PRId64,
352                     entry.data.i64[0], entryCopy.data.i64[0]);
353             return;
354         }
355 
356         if (thiz->mRegisteredPhysicalIds.size() != physicalResultCount) {
357             ALOGE("Error: Number of registered physical camera Ids %zu is different than received"
358                     " physical camera Ids %zu", thiz->mRegisteredPhysicalIds.size(),
359                     physicalResultCount);
360             return;
361         }
362         for (size_t i = 0; i < physicalResultCount; i++) {
363             if (physicalCameraIds[i] == nullptr) {
364                 ALOGE("Error: Invalid physical camera id in capture result");
365                 return;
366             }
367             if (physicalResults[i] == nullptr) {
368                 ALOGE("Error: Invalid physical camera metadata in capture result");
369                 return;
370             }
371             ACameraMetadata_const_entry physicalEntry;
372             auto ret = ACameraMetadata_getConstEntry(physicalResults[i], ACAMERA_SYNC_FRAME_NUMBER,
373                     &physicalEntry);
374             if (ret != ACAMERA_OK) {
375                 ALOGE("Error: Sync frame number missing from physical camera result metadata!");
376                 return;
377             }
378             if (physicalEntry.data.i64[0] != entryCopy.data.i64[0]) {
379                 ALOGE("Error: Physical camera sync frame number %" PRId64
380                         " mismatch result copy %" PRId64,
381                         physicalEntry.data.i64[0], entryCopy.data.i64[0]);
382                 return;
383             }
384 
385             auto foundId = std::find(thiz->mRegisteredPhysicalIds.begin(),
386                     thiz->mRegisteredPhysicalIds.end(), physicalCameraIds[i]);
387             if (foundId == thiz->mRegisteredPhysicalIds.end()) {
388                 ALOGE("Error: Returned physical camera Id %s is not registered",
389                         physicalCameraIds[i]);
390                 return;
391             }
392         }
393         ACameraMetadata_free(copy);
394 
395         if (thiz->mSaveCompletedRequests) {
396             thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
397         }
398 
399         thiz->mLastCompletedFrameNumber = entry.data.i64[0];
400         thiz->mResultCondition.notify_one();
401     }
402 
onCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ACameraCaptureFailure * failure)403     static void onCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
404             ACaptureRequest* /*request*/, ACameraCaptureFailure* failure) {
405         ALOGV("%s", __FUNCTION__);
406         if ((obj == nullptr) || (failure == nullptr)) {
407             return;
408         }
409         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
410         std::lock_guard<std::mutex> lock(thiz->mMutex);
411         thiz->mFailedFrameNumbers.insert(failure->frameNumber);
412         thiz->mResultCondition.notify_one();
413     }
414 
onLogicalCameraCaptureFailed(void * obj,ACameraCaptureSession *,ACaptureRequest *,ALogicalCameraCaptureFailure * failure)415     static void onLogicalCameraCaptureFailed(void* obj, ACameraCaptureSession* /*session*/,
416             ACaptureRequest* /*request*/, ALogicalCameraCaptureFailure* failure) {
417         ALOGV("%s", __FUNCTION__);
418         if ((obj == nullptr) || (failure == nullptr)) {
419             return;
420         }
421         if (failure->physicalCameraId != nullptr) {
422             ALOGV("%s: physicalCameraId: %s", __FUNCTION__, failure->physicalCameraId);
423         }
424         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
425         std::lock_guard<std::mutex> lock(thiz->mMutex);
426         thiz->mFailedFrameNumbers.insert(failure->captureFailure.frameNumber);
427         thiz->mResultCondition.notify_one();
428     }
429 
onCaptureSequenceCompleted(void * obj,ACameraCaptureSession *,int sequenceId,int64_t frameNumber)430     static void onCaptureSequenceCompleted(void* obj, ACameraCaptureSession* /*session*/,
431             int sequenceId, int64_t frameNumber) {
432         ALOGV("%s", __FUNCTION__);
433         if (obj == nullptr) {
434             return;
435         }
436         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
437         std::lock_guard<std::mutex> lock(thiz->mMutex);
438         thiz->mLastSequenceIdCompleted = sequenceId;
439         thiz->mLastSequenceFrameNumber = frameNumber;
440         thiz->mResultCondition.notify_one();
441     }
442 
onCaptureSequenceAborted(void *,ACameraCaptureSession *,int)443     static void onCaptureSequenceAborted(void* /*obj*/, ACameraCaptureSession* /*session*/,
444             int /*sequenceId*/) {
445         //Not used for now
446     }
447 
onCaptureBufferLost(void * obj,ACameraCaptureSession *,ACaptureRequest *,ANativeWindow *,int64_t frameNumber)448     static void onCaptureBufferLost(void* obj, ACameraCaptureSession* /*session*/,
449             ACaptureRequest* /*request*/, ANativeWindow* /*window*/, int64_t frameNumber) {
450         ALOGV("%s", __FUNCTION__);
451         if (obj == nullptr) {
452             return;
453         }
454         CaptureResultListener* thiz = reinterpret_cast<CaptureResultListener*>(obj);
455         std::lock_guard<std::mutex> lock(thiz->mMutex);
456         thiz->mLastLostFrameNumber = frameNumber;
457         thiz->mResultCondition.notify_one();
458     }
459 
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)460     int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
461         int64_t ret = -1;
462         std::unique_lock<std::mutex> l(mMutex);
463 
464         while (mLastSequenceIdCompleted != sequenceId) {
465             auto timeout = std::chrono::system_clock::now() +
466                            std::chrono::seconds(timeoutSec);
467             if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
468                 break;
469             }
470         }
471 
472         if (mLastSequenceIdCompleted == sequenceId) {
473             ret = mLastSequenceFrameNumber;
474         }
475 
476         return ret;
477     }
478 
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)479     bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
480         bool ret = false;
481         std::unique_lock<std::mutex> l(mMutex);
482 
483         while ((mLastCompletedFrameNumber != frameNumber) &&
484                 (mLastLostFrameNumber != frameNumber) && !checkForFailureLocked(frameNumber)) {
485             auto timeout = std::chrono::system_clock::now() +
486                            std::chrono::seconds(timeoutSec);
487             if (std::cv_status::timeout == mResultCondition.wait_until(l, timeout)) {
488                 break;
489             }
490         }
491 
492         if ((mLastCompletedFrameNumber == frameNumber) ||
493                 (mLastLostFrameNumber == frameNumber) || checkForFailureLocked(frameNumber)) {
494             ret = true;
495         }
496 
497         return ret;
498     }
499 
setRequestSave(bool enable)500     void setRequestSave(bool enable) {
501         std::unique_lock<std::mutex> l(mMutex);
502         if (!enable) {
503             clearSavedRequestsLocked();
504         }
505         mSaveCompletedRequests = enable;
506     }
507 
508     // The lifecycle of returned ACaptureRequest* is still managed by CaptureResultListener
getCompletedRequests(std::vector<ACaptureRequest * > * out)509     void getCompletedRequests(std::vector<ACaptureRequest*>* out) {
510         std::unique_lock<std::mutex> l(mMutex);
511         *out = mCompletedRequests;
512     }
513 
registerPhysicalResults(size_t physicalIdCnt,const char * const * physicalOutputs)514     void registerPhysicalResults(size_t physicalIdCnt, const char*const* physicalOutputs) {
515         std::unique_lock<std::mutex> l(mMutex);
516         mRegisteredPhysicalIds.clear();
517         for (size_t i = 0; i < physicalIdCnt; i++) {
518             mRegisteredPhysicalIds.push_back(physicalOutputs[i]);
519         }
520     }
521 
checkForFailure(int64_t frameNumber)522     bool checkForFailure(int64_t frameNumber) {
523         std::lock_guard<std::mutex> lock(mMutex);
524         return checkForFailureLocked(frameNumber);
525     }
526 
reset()527     void reset() {
528         std::lock_guard<std::mutex> lock(mMutex);
529         mLastSequenceIdCompleted = -1;
530         mLastSequenceFrameNumber = -1;
531         mLastCompletedFrameNumber = -1;
532         mLastLostFrameNumber = -1;
533         mSaveCompletedRequests = false;
534         clearSavedRequestsLocked();
535         clearFailedFrameNumbersLocked();
536     }
537 
538   private:
539     std::mutex mMutex;
540     std::condition_variable mResultCondition;
541     int mLastSequenceIdCompleted = -1;
542     int64_t mLastSequenceFrameNumber = -1;
543     int64_t mLastCompletedFrameNumber = -1;
544     int64_t mLastLostFrameNumber = -1;
545     std::set<int64_t> mFailedFrameNumbers;
546     bool    mSaveCompletedRequests = false;
547     std::vector<ACaptureRequest*> mCompletedRequests;
548     // Registered physical camera Ids that are being requested upon.
549     std::vector<std::string> mRegisteredPhysicalIds;
550 
clearSavedRequestsLocked()551     void clearSavedRequestsLocked() {
552         for (ACaptureRequest* req : mCompletedRequests) {
553             ACaptureRequest_free(req);
554         }
555         mCompletedRequests.clear();
556     }
557 
clearFailedFrameNumbersLocked()558     void clearFailedFrameNumbersLocked() {
559         mFailedFrameNumbers.clear();
560     }
561 
checkForFailureLocked(int64_t frameNumber)562     bool checkForFailureLocked(int64_t frameNumber) {
563         return mFailedFrameNumbers.find(frameNumber) != mFailedFrameNumbers.end();
564     }
565 };
566 
567 class ImageReaderListener {
568   public:
569     // count, acquire, validate, and delete AImage when a new image is available
validateImageCb(void * obj,AImageReader * reader)570     static void validateImageCb(void* obj, AImageReader* reader) {
571         ALOGV("%s", __FUNCTION__);
572         if (obj == nullptr) {
573             return;
574         }
575         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
576         std::lock_guard<std::mutex> lock(thiz->mMutex);
577         thiz->mOnImageAvailableCount++;
578 
579         AImage* img = nullptr;
580         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
581         if (ret != AMEDIA_OK || img == nullptr) {
582             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
583                     __FUNCTION__, reader, ret, img);
584             return;
585         }
586 
587         // TODO: validate image content
588         int32_t format = -1;
589         ret = AImage_getFormat(img, &format);
590         if (ret != AMEDIA_OK || format == -1) {
591             ALOGE("%s: get format for image %p failed! ret: %d, format %d",
592                     __FUNCTION__, img, ret, format);
593         }
594 
595         // Save jpeg to SD card
596         if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
597             int32_t numPlanes = 0;
598             ret = AImage_getNumberOfPlanes(img, &numPlanes);
599             if (ret != AMEDIA_OK || numPlanes != 1) {
600                 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
601                         __FUNCTION__, img, ret, numPlanes);
602                 AImage_delete(img);
603                 return;
604             }
605 
606             int32_t width = -1, height = -1;
607             ret = AImage_getWidth(img, &width);
608             if (ret != AMEDIA_OK || width <= 0) {
609                 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
610                         __FUNCTION__, img, ret, width);
611                 AImage_delete(img);
612                 return;
613             }
614 
615             ret = AImage_getHeight(img, &height);
616             if (ret != AMEDIA_OK || height <= 0) {
617                 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
618                         __FUNCTION__, img, ret, height);
619                 AImage_delete(img);
620                 return;
621             }
622 
623             uint8_t* data = nullptr;
624             int dataLength = 0;
625             ret =  AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
626             if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
627                 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
628                         __FUNCTION__, img, ret, data, dataLength);
629                 AImage_delete(img);
630                 return;
631             }
632 
633 #if 0
634             char dumpFilePath[512];
635             sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
636             ALOGI("Writing jpeg file to %s", dumpFilePath);
637             FILE* file = fopen(dumpFilePath,"w+");
638 
639             if (file != nullptr) {
640                 fwrite(data, 1, dataLength, file);
641                 fflush(file);
642                 fclose(file);
643             }
644 #endif
645         }
646 
647         AImage_delete(img);
648     }
649 
650     // count, acquire image but not delete the image
acquireImageCb(void * obj,AImageReader * reader)651     static void acquireImageCb(void* obj, AImageReader* reader) {
652         ALOGV("%s", __FUNCTION__);
653         if (obj == nullptr) {
654             return;
655         }
656         ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
657         std::lock_guard<std::mutex> lock(thiz->mMutex);
658         thiz->mOnImageAvailableCount++;
659 
660         // Acquire, but not closing.
661         AImage* img = nullptr;
662         media_status_t ret = AImageReader_acquireNextImage(reader, &img);
663         if (ret != AMEDIA_OK || img == nullptr) {
664             ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
665                     __FUNCTION__, reader, ret, img);
666             return;
667         }
668         return;
669     }
670 
onImageAvailableCount()671     int onImageAvailableCount() {
672         std::lock_guard<std::mutex> lock(mMutex);
673         return mOnImageAvailableCount;
674     }
675 
setDumpFilePathBase(const char * path)676     void setDumpFilePathBase(const char* path) {
677         std::lock_guard<std::mutex> lock(mMutex);
678         mDumpFilePathBase = path;
679     }
680 
681   private:
682     // TODO: add mReader to make sure each listener is associated to one reader?
683     std::mutex mMutex;
684     int mOnImageAvailableCount = 0;
685     const char* mDumpFilePathBase = nullptr;
686 };
687 
688 class StaticInfo {
689   public:
StaticInfo(ACameraMetadata * chars)690     explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
691 
isColorOutputSupported()692     bool isColorOutputSupported() {
693         return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
694     }
695 
isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap)696     bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
697         ACameraMetadata_const_entry entry;
698         ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
699         for (uint32_t i = 0; i < entry.count; i++) {
700             if (entry.data.u8[i] == cap) {
701                 return true;
702             }
703         }
704         return false;
705     }
706 
getMinFrameDurationFor(int64_t format,int64_t width,int64_t height)707     int64_t getMinFrameDurationFor(int64_t format, int64_t width, int64_t height) {
708         int32_t minFrameDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
709                 ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS :
710                 (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
711                 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS :
712                 ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
713         return getDurationFor(minFrameDurationTag, format, width, height);
714     }
715 
getStallDurationFor(int64_t format,int64_t width,int64_t height)716     int64_t getStallDurationFor(int64_t format, int64_t width, int64_t height) {
717         int32_t stallDurationTag = (format == AIMAGE_FORMAT_HEIC) ?
718                 ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS : (format == AIMAGE_FORMAT_DEPTH_JPEG) ?
719                 ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS :
720                 ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS;
721         return getDurationFor(stallDurationTag, format, width, height);
722     }
723 
getMaxSizeForFormat(int32_t format,int32_t * width,int32_t * height)724     bool getMaxSizeForFormat(int32_t format, int32_t *width, int32_t *height) {
725         ACameraMetadata_const_entry entry;
726 
727         int32_t streamConfigTag, streamConfigOutputTag;
728         switch (format) {
729             case AIMAGE_FORMAT_HEIC:
730                 streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
731                 streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
732                 break;
733             case AIMAGE_FORMAT_DEPTH_JPEG:
734                 streamConfigTag = ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS;
735                 streamConfigOutputTag =
736                         ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT;
737                 break;
738             case AIMAGE_FORMAT_JPEG:
739             case AIMAGE_FORMAT_Y8:
740             default:
741                 streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
742                 streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
743                 break;
744         }
745 
746         bool supported = false;
747         camera_status_t status = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
748         if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
749             return supported;
750         }
751 
752        int32_t w = 0, h = 0;
753         for (uint32_t i = 0; i < entry.count; i += 4) {
754             if (entry.data.i32[i] == format &&
755                     entry.data.i32[i+3] == streamConfigOutputTag &&
756                     entry.data.i32[i+1] * entry.data.i32[i+2] > w * h) {
757                 w = entry.data.i32[i+1];
758                 h = entry.data.i32[i+2];
759                 supported = true;
760             }
761         }
762 
763         if (supported) {
764             *width = w;
765             *height = h;
766         }
767         return supported;
768     }
769 
isSizeSupportedForFormat(int32_t format,int32_t width,int32_t height)770     bool isSizeSupportedForFormat(int32_t format, int32_t width, int32_t height) {
771         ACameraMetadata_const_entry entry;
772 
773         int32_t streamConfigTag, streamConfigOutputTag;
774         switch (format) {
775             case AIMAGE_FORMAT_HEIC:
776                 streamConfigTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS;
777                 streamConfigOutputTag = ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT;
778                 break;
779             case AIMAGE_FORMAT_JPEG:
780             case AIMAGE_FORMAT_Y8:
781             default:
782                 streamConfigTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
783                 streamConfigOutputTag = ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
784                 break;
785         }
786 
787         auto ret = ACameraMetadata_getConstEntry(mChars, streamConfigTag, &entry);
788         if (ret != ACAMERA_OK) {
789             return false;
790         }
791         for (uint32_t i = 0; i < entry.count; i += 4) {
792             if (entry.data.i32[i] == format &&
793                     entry.data.i32[i+3] == streamConfigOutputTag &&
794                     entry.data.i32[i+1] == width &&
795                     entry.data.i32[i+2] == height) {
796                 return true;
797             }
798         }
799         return false;
800     }
801   private:
getDurationFor(uint32_t tag,int64_t format,int64_t width,int64_t height)802     int64_t getDurationFor(uint32_t tag, int64_t format, int64_t width, int64_t height) {
803         if (tag != ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS &&
804                 tag != ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS &&
805                 tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS &&
806                 tag != ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS &&
807                 tag != ACAMERA_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS &&
808                 tag != ACAMERA_HEIC_AVAILABLE_HEIC_STALL_DURATIONS &&
809                 tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS &&
810                 tag != ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS) {
811             return -1;
812         }
813         ACameraMetadata_const_entry entry;
814         ACameraMetadata_getConstEntry(mChars, tag, &entry);
815         for (uint32_t i = 0; i < entry.count; i += 4) {
816             if (entry.data.i64[i] == format &&
817                     entry.data.i64[i+1] == width &&
818                     entry.data.i64[i+2] == height) {
819                 return entry.data.i64[i+3];
820             }
821         }
822         return -1;
823     }
824     const ACameraMetadata* mChars;
825 };
826 
827 class PreviewTestCase {
828   public:
~PreviewTestCase()829     ~PreviewTestCase() {
830         resetCamera();
831         deInit();
832         if (mCameraManager) {
833             ACameraManager_delete(mCameraManager);
834             mCameraManager = nullptr;
835         }
836     }
837 
PreviewTestCase()838     PreviewTestCase() {
839         // create is guaranteed to succeed;
840         createManager();
841     }
842 
843     // Free all resources except camera manager
resetCamera()844     void resetCamera() {
845         mSessionListener.reset();
846         mResultListener.reset();
847         if (mSession) {
848             ACameraCaptureSession_close(mSession);
849             mSession = nullptr;
850         }
851         if (mDevice) {
852             ACameraDevice_close(mDevice);
853             mDevice = nullptr;
854         }
855         if (mImgReader) {
856             AImageReader_delete(mImgReader);
857             // No need to call ANativeWindow_release on imageReaderAnw
858             mImgReaderAnw = nullptr;
859             mImgReader = nullptr;
860         }
861         if (mPreviewAnw) {
862             ANativeWindow_release(mPreviewAnw);
863             mPreviewAnw = nullptr;
864         }
865         if (mOutputs) {
866             ACaptureSessionOutputContainer_free(mOutputs);
867             mOutputs = nullptr;
868         }
869         if (mPreviewOutput) {
870             ACaptureSessionOutput_free(mPreviewOutput);
871             mPreviewOutput = nullptr;
872         }
873         if (mImgReaderOutput) {
874             ACaptureSessionOutput_free(mImgReaderOutput);
875             mImgReaderOutput = nullptr;
876         }
877         if (mPreviewRequest) {
878             ACaptureRequest_free(mPreviewRequest);
879             mPreviewRequest = nullptr;
880         }
881         if (mStillRequest) {
882             ACaptureRequest_free(mStillRequest);
883             mStillRequest = nullptr;
884         }
885         if (mReqPreviewOutput) {
886             ACameraOutputTarget_free(mReqPreviewOutput);
887             mReqPreviewOutput = nullptr;
888         }
889         if (mReqImgReaderOutput) {
890             ACameraOutputTarget_free(mReqImgReaderOutput);
891             mReqImgReaderOutput = nullptr;
892         }
893 
894         mImgReaderInited = false;
895         mPreviewInited = false;
896     }
897 
initWithErrorLog()898     camera_status_t initWithErrorLog() {
899         camera_status_t ret = ACameraManager_getCameraIdList(
900                 mCameraManager, &mCameraIdList);
901         if (ret != ACAMERA_OK) {
902             LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
903             return ret;
904         }
905         ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
906         if (ret != ACAMERA_OK) {
907             LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
908             return ret;
909         }
910         mMgrInited = true;
911         return ACAMERA_OK;
912     }
913 
deInit()914     camera_status_t deInit () {
915         if (!mMgrInited) {
916             return ACAMERA_OK;
917         }
918 
919         camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
920                 mCameraManager, &mServiceCb);
921         if (ret != ACAMERA_OK) {
922             ALOGE("Unregister availability callback failed: ret %d", ret);
923             return ret;
924         }
925 
926         if (mCameraIdList) {
927             ACameraManager_deleteCameraIdList(mCameraIdList);
928             mCameraIdList = nullptr;
929         }
930         mMgrInited = false;
931         return ACAMERA_OK;
932     }
933 
getNumCameras()934     int getNumCameras() {
935         if (!mMgrInited || !mCameraIdList) {
936             return -1;
937         }
938         return mCameraIdList->numCameras;
939     }
940 
getCameraId(int idx)941     const char* getCameraId(int idx) {
942         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
943             return nullptr;
944         }
945         return mCameraIdList->cameraIds[idx];
946     }
947 
948     // Caller is responsible to free returned characteristics metadata
getCameraChars(int idx)949     ACameraMetadata* getCameraChars(int idx) {
950         if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
951             return nullptr;
952         }
953 
954         ACameraMetadata* chars;
955         camera_status_t ret = ACameraManager_getCameraCharacteristics(
956                 mCameraManager, mCameraIdList->cameraIds[idx], &chars);
957         if (ret != ACAMERA_OK) {
958             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
959             return nullptr;
960         }
961         return chars;
962     }
963 
964     // Caller is responsible to free returned characteristics metadata.
getCameraChars(const char * id)965     ACameraMetadata* getCameraChars(const char* id) {
966         if (!mMgrInited || id == nullptr) {
967             return nullptr;
968         }
969 
970         ACameraMetadata* chars;
971         camera_status_t ret = ACameraManager_getCameraCharacteristics(mCameraManager, id, &chars);
972         if (ret != ACAMERA_OK) {
973             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
974             return nullptr;
975         }
976         return chars;
977     }
978 
updateOutput(JNIEnv * env,ACaptureSessionOutput * output)979     camera_status_t updateOutput(JNIEnv* env, ACaptureSessionOutput *output) {
980         if (mSession == nullptr) {
981             ALOGE("Testcase cannot update output configuration session %p",
982                     mSession);
983             return ACAMERA_ERROR_UNKNOWN;
984         }
985 
986         return ACameraCaptureSession_updateSharedOutput(mSession, output);
987     }
988 
openCamera(const char * cameraId)989     camera_status_t openCamera(const char* cameraId) {
990         if (mDevice) {
991             ALOGE("Cannot open camera before closing previously open one");
992             return ACAMERA_ERROR_INVALID_PARAMETER;
993         }
994         mCameraId = cameraId;
995         return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
996     }
997 
closeCamera()998     camera_status_t closeCamera() {
999         camera_status_t ret = ACameraDevice_close(mDevice);
1000         mDevice = nullptr;
1001         return ret;
1002     }
1003 
isCameraAvailable(const char * cameraId)1004     bool isCameraAvailable(const char* cameraId) {
1005         if (!mMgrInited) {
1006             ALOGE("Camera service listener has not been registered!");
1007         }
1008         return mServiceListener.isAvailable(cameraId);
1009     }
1010 
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener)1011     media_status_t initImageReaderWithErrorLog(
1012             int32_t width, int32_t height, int32_t format, int32_t maxImages,
1013             AImageReader_ImageListener* listener) {
1014         if (mImgReader || mImgReaderAnw) {
1015             LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
1016             return AMEDIA_ERROR_UNKNOWN;
1017         }
1018 
1019         media_status_t ret = initImageReaderWithErrorLog(
1020                 width, height, format, maxImages, listener, &mImgReader,
1021                 &mImgReaderAnw);
1022         if (ret != AMEDIA_OK) {
1023             return ret;
1024         }
1025 
1026         mImgReaderInited = true;
1027         return AMEDIA_OK;
1028     }
1029 
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages,AImageReader_ImageListener * listener,AImageReader ** imgReader,ANativeWindow ** imgReaderAnw)1030     media_status_t initImageReaderWithErrorLog(
1031             int32_t width, int32_t height, int32_t format, int32_t maxImages,
1032             AImageReader_ImageListener* listener, AImageReader **imgReader,
1033             ANativeWindow **imgReaderAnw) {
1034 
1035         media_status_t ret = AImageReader_new(
1036                 width, height, format,
1037                 maxImages, imgReader);
1038         if (ret != AMEDIA_OK) {
1039             LOG_ERROR(errorString, "Create image reader. ret %d", ret);
1040             return ret;
1041         }
1042         if (*imgReader == nullptr) {
1043             LOG_ERROR(errorString, "null image reader created");
1044             return AMEDIA_ERROR_UNKNOWN;
1045         }
1046 
1047         ret = AImageReader_setImageListener(*imgReader, listener);
1048         if (ret != AMEDIA_OK) {
1049             LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
1050             return ret;
1051         }
1052 
1053         ret = AImageReader_getWindow(*imgReader, imgReaderAnw);
1054         if (ret != AMEDIA_OK) {
1055             LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
1056             return ret;
1057         }
1058         if (*imgReaderAnw == nullptr) {
1059             LOG_ERROR(errorString, "Null ANW from AImageReader!");
1060             return AMEDIA_ERROR_UNKNOWN;
1061         }
1062         return AMEDIA_OK;
1063     }
1064 
initPreviewAnw(JNIEnv * env,jobject jSurface)1065     ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
1066         if (mPreviewAnw) {
1067             ALOGE("Cannot init preview twice!");
1068             return nullptr;
1069         }
1070         mPreviewAnw =  ANativeWindow_fromSurface(env, jSurface);
1071         mPreviewInited = true;
1072         return mPreviewAnw;
1073     }
1074 
createCaptureSessionWithLog(bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)1075     camera_status_t createCaptureSessionWithLog(bool isPreviewShared = false,
1076             ACaptureRequest *sessionParameters = nullptr) {
1077         std::vector<ACaptureSessionOutput*> extraOutputs;
1078         return createCaptureSessionWithLog(extraOutputs, isPreviewShared, sessionParameters);
1079     }
1080 
createCaptureSessionOutputContainer(const std::vector<ACaptureSessionOutput * > extraOutputs,ACaptureSessionOutputContainer ** outputs,bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr)1081     camera_status_t createCaptureSessionOutputContainer(
1082             const std::vector<ACaptureSessionOutput*> extraOutputs,
1083             ACaptureSessionOutputContainer** outputs,
1084             bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr) {
1085         if (!mMgrInited || (!mImgReaderInited && !mPreviewInited) || !outputs) {
1086             LOG_ERROR(errorString, "Cannot create session output container. mgrInit %d "
1087                     "readerInit %d previewInit %d outputs %p",
1088                     mMgrInited, mImgReaderInited, mPreviewInited, outputs);
1089             return ACAMERA_ERROR_UNKNOWN;
1090         }
1091 
1092         camera_status_t ret = ACaptureSessionOutputContainer_create(outputs);
1093         if (ret != ACAMERA_OK) {
1094             LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
1095             return ret;
1096         }
1097 
1098         if (mImgReaderInited) {
1099             ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
1100             if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
1101                 LOG_ERROR(errorString,
1102                         "Session image reader output create fail! ret %d output %p",
1103                         ret, mImgReaderOutput);
1104                 if (ret == ACAMERA_OK) {
1105                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
1106                 }
1107                 return ret;
1108             }
1109 
1110             ret = ACaptureSessionOutputContainer_add(*outputs, mImgReaderOutput);
1111             if (ret != ACAMERA_OK) {
1112                 LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
1113                 return ret;
1114             }
1115         }
1116 
1117         for (auto extraOutput : extraOutputs) {
1118             ret = ACaptureSessionOutputContainer_add(*outputs, extraOutput);
1119             if (ret != ACAMERA_OK) {
1120                 LOG_ERROR(errorString, "Session image reader output add failed! ret %d", ret);
1121                 return ret;
1122             }
1123         }
1124 
1125         if (mPreviewInited) {
1126             if (isPreviewShared) {
1127                 ret = ACaptureSessionSharedOutput_create(mPreviewAnw, &mPreviewOutput);
1128             } else {
1129                 ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
1130             }
1131             if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
1132                 LOG_ERROR(errorString,
1133                         "Session preview output create fail! ret %d output %p",
1134                         ret, mPreviewOutput);
1135                 if (ret == ACAMERA_OK) {
1136                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
1137                 }
1138                 return ret;
1139             }
1140 
1141             ret = ACaptureSessionOutputContainer_add(*outputs, mPreviewOutput);
1142             if (ret != ACAMERA_OK) {
1143                 LOG_ERROR(errorString, "Session preview output add failed! ret %d", ret);
1144                 return ret;
1145             }
1146         }
1147         return ret;
1148     }
1149 
createCaptureSessionWithLog(const std::vector<ACaptureSessionOutput * > extraOutputs,bool isPreviewShared=false,ACaptureRequest * sessionParameters=nullptr,bool sessionConfigurationDefault=true)1150     camera_status_t createCaptureSessionWithLog(
1151             const std::vector<ACaptureSessionOutput*> extraOutputs,
1152             bool isPreviewShared = false, ACaptureRequest *sessionParameters = nullptr,
1153             bool sessionConfigurationDefault = true) {
1154         if (mSession) {
1155             LOG_ERROR(errorString, "Cannot create session before closing existing one");
1156             return ACAMERA_ERROR_UNKNOWN;
1157         }
1158 
1159         camera_status_t ret = createCaptureSessionOutputContainer(
1160                 extraOutputs, &mOutputs, isPreviewShared, sessionParameters);
1161         if (ret != ACAMERA_OK) {
1162             LOG_ERROR(errorString, "Failed to create session output container! ret %d", ret);
1163             return ret;
1164         }
1165 
1166         ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
1167         if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION &&
1168                 ret != ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
1169             LOG_ERROR(errorString, "isSessionConfigurationSupported must return either OK "
1170                     ", UNSUPPORTED_OPERATION, or STREAM_CONFIGURE_FAIL, but returns %d", ret);
1171             return ret;
1172         }
1173 
1174         // If session configuration is not supported by default, return early
1175         // when camera device doesn't explicitly claim support.
1176         if (ret != ACAMERA_OK && !sessionConfigurationDefault) {
1177             return ret;
1178         }
1179 
1180         ret = ACameraDevice_createCaptureSessionWithSessionParameters(
1181                 mDevice, mOutputs, sessionParameters, &mSessionCb, &mSession);
1182         if (ret != ACAMERA_OK || mSession == nullptr) {
1183             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
1184                     mCameraId, ret, mSession);
1185             if (ret == ACAMERA_OK) {
1186                 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
1187             }
1188             return ret;
1189         }
1190 
1191         return ACAMERA_OK;
1192     }
1193 
closeSession()1194     void closeSession() {
1195         if (mSession != nullptr) {
1196             ACameraCaptureSession_close(mSession);
1197         }
1198         if (mOutputs) {
1199             ACaptureSessionOutputContainer_free(mOutputs);
1200             mOutputs = nullptr;
1201         }
1202         if (mPreviewOutput) {
1203             ACaptureSessionOutput_free(mPreviewOutput);
1204             mPreviewOutput = nullptr;
1205         }
1206         if (mImgReaderOutput) {
1207             ACaptureSessionOutput_free(mImgReaderOutput);
1208             mImgReaderOutput = nullptr;
1209         }
1210         mSession = nullptr;
1211     }
1212 
createRequestsWithErrorLog()1213     camera_status_t createRequestsWithErrorLog() {
1214         std::vector<ACameraOutputTarget*> extraOutputs;
1215         return createRequestsWithErrorLog(extraOutputs);
1216     }
1217 
createRequestsWithErrorLog(const std::vector<ACameraOutputTarget * > extraOutputs,const ACameraIdList * physicalCameraIdList=nullptr)1218     camera_status_t createRequestsWithErrorLog(
1219                 const std::vector<ACameraOutputTarget*> extraOutputs,
1220                 const ACameraIdList* physicalCameraIdList = nullptr) {
1221         if (mPreviewRequest || mStillRequest) {
1222             LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
1223             return ACAMERA_ERROR_UNKNOWN;
1224         }
1225 
1226         if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
1227             LOG_ERROR(errorString,
1228                     "Cannot create request. device %p previewInit %d readeInit %d",
1229                     mDevice, mPreviewInited, mImgReaderInited);
1230             return ACAMERA_ERROR_UNKNOWN;
1231         }
1232 
1233         camera_status_t ret;
1234         bool usePhysicalSettings = (physicalCameraIdList != nullptr);
1235         if (mPreviewInited) {
1236             if (!usePhysicalSettings) {
1237                 ret = ACameraDevice_createCaptureRequest(
1238                         mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
1239             } else {
1240                 ret = ACameraDevice_createCaptureRequest_withPhysicalIds(
1241                         mDevice, TEMPLATE_PREVIEW, physicalCameraIdList, &mPreviewRequest);
1242             }
1243             if (ret != ACAMERA_OK) {
1244                 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
1245                         mCameraId, ret);
1246                 return ret;
1247             }
1248 
1249             if (usePhysicalSettings) {
1250                 for (int i = 0; i < physicalCameraIdList->numCameras; i++) {
1251                     // Check physical camera specific metadata functions.
1252                     uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
1253                     ret = ACaptureRequest_setEntry_physicalCamera_u8(mPreviewRequest,
1254                             physicalCameraIdList->cameraIds[i], ACAMERA_CONTROL_AE_MODE,
1255                             1 /*count*/, &aeMode);
1256                     if (ret != ACAMERA_OK) {
1257                         LOG_ERROR(errorString,
1258                             "Error: Camera %s update AE mode key fail. ret %d",
1259                             physicalCameraIdList->cameraIds[i], ret);
1260                         return ret;
1261                     }
1262 
1263                     ACameraMetadata_const_entry entry;
1264                     ret = ACaptureRequest_getConstEntry_physicalCamera(mPreviewRequest,
1265                                 physicalCameraIdList->cameraIds[i],
1266                                 ACAMERA_CONTROL_AE_MODE, &entry);
1267                     if (ret != ACAMERA_OK) {
1268                         LOG_ERROR(errorString, "Get AE mode key for physicalCamera %s failed."
1269                                 " ret %d", physicalCameraIdList->cameraIds[i], ret);
1270                         return ret;
1271                     }
1272                     if (entry.data.u8[0] != aeMode) {
1273                         LOG_ERROR(errorString,
1274                             "Error: AE mode key is not updated. expect %d but get %d",
1275                             aeMode, entry.data.u8[0]);
1276                         return ACAMERA_ERROR_UNKNOWN;
1277                     }
1278                 }
1279             }
1280 
1281             ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
1282             if (ret != ACAMERA_OK) {
1283                 LOG_ERROR(errorString,
1284                         "Camera %s create request preview output target failed. ret %d",
1285                         mCameraId, ret);
1286                 return ret;
1287             }
1288 
1289             ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
1290             if (ret != ACAMERA_OK) {
1291                 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
1292                         mCameraId, ret);
1293                 return ret;
1294             }
1295 
1296             // Add extraOutputs to the request
1297             for (auto extraOutput : extraOutputs) {
1298                 ret = ACaptureRequest_addTarget(mPreviewRequest, extraOutput);
1299                 if (ret != ACAMERA_OK) {
1300                     LOG_ERROR(errorString, "Camera %s add extra request output failed. ret %d",
1301                             mCameraId, ret);
1302                     return ret;
1303                 }
1304             }
1305         } else {
1306             ALOGI("Preview not inited. Will not create preview request!");
1307         }
1308 
1309         if (mImgReaderInited) {
1310             ret = ACameraDevice_createCaptureRequest(
1311                     mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
1312             if (ret != ACAMERA_OK) {
1313                 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
1314                         mCameraId, ret);
1315                 return ret;
1316             }
1317 
1318             ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
1319             if (ret != ACAMERA_OK) {
1320                 LOG_ERROR(errorString,
1321                         "Camera %s create request reader output target failed. ret %d",
1322                         mCameraId, ret);
1323                 return ret;
1324             }
1325 
1326             ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
1327             if (ret != ACAMERA_OK) {
1328                 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
1329                         mCameraId, ret);
1330                 return ret;
1331             }
1332 
1333             if (mPreviewInited) {
1334                 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
1335                 if (ret != ACAMERA_OK) {
1336                     LOG_ERROR(errorString,
1337                             "Camera %s add still request preview output failed. ret %d",
1338                             mCameraId, ret);
1339                     return ret;
1340                 }
1341             }
1342         } else {
1343             ALOGI("AImageReader not inited. Will not create still request!");
1344         }
1345 
1346         return ACAMERA_OK;
1347     }
1348 
1349     // The output ACaptureRequest* is still managed by testcase class
getStillRequest(ACaptureRequest ** out)1350     camera_status_t getStillRequest(ACaptureRequest** out) {
1351         if (mStillRequest == nullptr) {
1352             ALOGE("Camera %s Still capture request hasn't been created", mCameraId);
1353             return ACAMERA_ERROR_INVALID_PARAMETER;
1354         }
1355         *out = mStillRequest;
1356         return ACAMERA_OK;
1357     }
1358 
getPreviewRequest(ACaptureRequest ** out)1359     camera_status_t getPreviewRequest(ACaptureRequest** out) {
1360         if (mPreviewRequest == nullptr) {
1361             ALOGE("Camera %s Preview capture request hasn't been created", mCameraId);
1362             return ACAMERA_ERROR_INVALID_PARAMETER;
1363         }
1364         *out = mPreviewRequest;
1365         return ACAMERA_OK;
1366     }
1367 
startPreview(int * sequenceId=nullptr,size_t physicalIdCnt=0,const char * const * extraPhysicalOutputs=nullptr)1368     camera_status_t startPreview(int *sequenceId = nullptr, size_t physicalIdCnt = 0,
1369             const char*const* extraPhysicalOutputs = nullptr) {
1370         if (mSession == nullptr || mPreviewRequest == nullptr) {
1371             ALOGE("Testcase cannot start preview: session %p, preview request %p",
1372                     mSession, mPreviewRequest);
1373             return ACAMERA_ERROR_UNKNOWN;
1374         }
1375         int previewSeqId;
1376         camera_status_t ret;
1377         if (sequenceId == nullptr) {
1378             ret = ACameraCaptureSession_setRepeatingRequest(
1379                    mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
1380         } else if (physicalIdCnt == 0) {
1381             ret = ACameraCaptureSession_setRepeatingRequest(
1382                    mSession, &mResultCb, 1, &mPreviewRequest, sequenceId);
1383         } else {
1384             if (extraPhysicalOutputs == nullptr) {
1385                 ALOGE("Testcase missing valid physical camera Ids for logical camera");
1386                 return ACAMERA_ERROR_INVALID_PARAMETER;
1387             }
1388             CaptureResultListener* resultListener =
1389                     static_cast<CaptureResultListener*>(mLogicalCameraResultCb.context);
1390             resultListener->registerPhysicalResults(physicalIdCnt, extraPhysicalOutputs);
1391             ret = ACameraCaptureSession_logicalCamera_setRepeatingRequest(
1392                     mSession, &mLogicalCameraResultCb, 1, &mPreviewRequest, sequenceId);
1393         }
1394         return ret;
1395     }
1396 
startRepeatingRequest(int * sequenceId,ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * resultCb)1397     camera_status_t startRepeatingRequest(int *sequenceId, ACaptureRequest *request,
1398             ACameraCaptureSession_captureCallbacks *resultCb) {
1399         if (mSession == nullptr || request == nullptr || resultCb == nullptr) {
1400             ALOGE("Testcase cannot start repeating request: session %p, request %p resultCb %p",
1401                     mSession, request, resultCb);
1402             return ACAMERA_ERROR_UNKNOWN;
1403         }
1404 
1405         return ACameraCaptureSession_setRepeatingRequest(mSession, resultCb, 1, &request,
1406                 sequenceId);
1407     }
1408 
stopPreview()1409     camera_status_t stopPreview() {
1410         if (mSession == nullptr) {
1411             ALOGE("Testcase cannot stop preview: session %p", mSession);
1412             return ACAMERA_ERROR_UNKNOWN;
1413         }
1414         return ACameraCaptureSession_stopRepeating(mSession);
1415     }
1416 
updateRepeatingRequest(ACaptureRequest * updatedRequest,int * sequenceId=nullptr)1417     camera_status_t updateRepeatingRequest(ACaptureRequest *updatedRequest,
1418             int *sequenceId = nullptr) {
1419         if (mSession == nullptr || updatedRequest == nullptr) {
1420             ALOGE("Testcase cannot update repeating request: session %p, updated request %p",
1421                     mSession, updatedRequest);
1422             return ACAMERA_ERROR_UNKNOWN;
1423         }
1424 
1425         int previewSeqId;
1426         camera_status_t ret;
1427         if (sequenceId == nullptr) {
1428             ret = ACameraCaptureSession_setRepeatingRequest(
1429                     mSession, nullptr, 1, &updatedRequest, &previewSeqId);
1430         } else {
1431             ret = ACameraCaptureSession_setRepeatingRequest(
1432                     mSession, &mResultCb, 1, &updatedRequest, sequenceId);
1433         }
1434         return ret;
1435     }
1436 
getCaptureSequenceLastFrameNumber(int64_t sequenceId,uint32_t timeoutSec)1437     int64_t getCaptureSequenceLastFrameNumber(int64_t sequenceId, uint32_t timeoutSec) {
1438         return mResultListener.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
1439     }
1440 
waitForFrameNumber(int64_t frameNumber,uint32_t timeoutSec)1441     bool waitForFrameNumber(int64_t frameNumber, uint32_t timeoutSec) {
1442         return mResultListener.waitForFrameNumber(frameNumber, timeoutSec);
1443     }
1444 
takePicture()1445     camera_status_t takePicture() {
1446         if (mSession == nullptr || mStillRequest == nullptr) {
1447             ALOGE("Testcase cannot take picture: session %p, still request %p",
1448                     mSession, mStillRequest);
1449             return ACAMERA_ERROR_UNKNOWN;
1450         }
1451         int seqId;
1452         return ACameraCaptureSession_capture(
1453                 mSession, nullptr, 1, &mStillRequest, &seqId);
1454     }
1455 
capture(ACaptureRequest * request,ACameraCaptureSession_captureCallbacks * listener,int * seqId)1456     camera_status_t capture(ACaptureRequest* request,
1457             ACameraCaptureSession_captureCallbacks* listener,
1458             /*out*/int* seqId) {
1459         if (mSession == nullptr || request == nullptr) {
1460             ALOGE("Testcase cannot capture session: session %p, request %p",
1461                     mSession, request);
1462             return ACAMERA_ERROR_UNKNOWN;
1463         }
1464         return ACameraCaptureSession_capture(
1465                 mSession, listener, 1, &request, seqId);
1466     }
1467 
resetWithErrorLog()1468     camera_status_t resetWithErrorLog() {
1469         camera_status_t ret;
1470 
1471         closeSession();
1472 
1473         for (int i = 0; i < 50; i++) {
1474             usleep(100000); // sleep 100ms
1475             if (mSessionListener.isClosed()) {
1476                 ALOGI("Session take ~%d ms to close", i*100);
1477                 break;
1478             }
1479         }
1480 
1481         if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
1482             LOG_ERROR(errorString,
1483                     "Session for camera %s close error. isClosde %d close count %d",
1484                     mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
1485             return ACAMERA_ERROR_UNKNOWN;
1486         }
1487         mSessionListener.reset();
1488         mResultListener.reset();
1489 
1490         ret = closeCamera();
1491         if (ret != ACAMERA_OK) {
1492             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
1493             return ret;
1494         }
1495 
1496         resetCamera();
1497         return ACAMERA_OK;
1498     }
1499 
getSessionListener()1500     CaptureSessionListener* getSessionListener() {
1501         return &mSessionListener;
1502     }
1503 
getCameraDevice()1504     ACameraDevice* getCameraDevice() {
1505         return mDevice;
1506     }
1507 
getPreviewOutput()1508     ACaptureSessionOutput *getPreviewOutput() {
1509         return mPreviewOutput;
1510     }
1511 
1512   private:
createManager()1513     ACameraManager* createManager() {
1514         if (!mCameraManager) {
1515             mCameraManager = ACameraManager_create();
1516         }
1517         return mCameraManager;
1518     }
1519 
1520     CameraServiceListener mServiceListener;
1521     ACameraManager_AvailabilityCallbacks mServiceCb {
1522         &mServiceListener,
1523         CameraServiceListener::onAvailable,
1524         CameraServiceListener::onUnavailable
1525     };
1526     CameraDeviceListener mDeviceListener;
1527     ACameraDevice_StateCallbacks mDeviceCb {
1528         &mDeviceListener,
1529         CameraDeviceListener::onDisconnected,
1530         CameraDeviceListener::onError
1531     };
1532     CaptureSessionListener mSessionListener;
1533     ACameraCaptureSession_stateCallbacks mSessionCb {
1534         &mSessionListener,
1535         CaptureSessionListener::onClosed,
1536         CaptureSessionListener::onReady,
1537         CaptureSessionListener::onActive
1538     };
1539 
1540     CaptureResultListener mResultListener;
1541     ACameraCaptureSession_captureCallbacks mResultCb {
1542         &mResultListener,
1543         CaptureResultListener::onCaptureStart,
1544         CaptureResultListener::onCaptureProgressed,
1545         CaptureResultListener::onCaptureCompleted,
1546         CaptureResultListener::onCaptureFailed,
1547         CaptureResultListener::onCaptureSequenceCompleted,
1548         CaptureResultListener::onCaptureSequenceAborted,
1549         CaptureResultListener::onCaptureBufferLost
1550     };
1551 
1552     ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCameraResultCb {
1553         &mResultListener,
1554         CaptureResultListener::onCaptureStart,
1555         CaptureResultListener::onCaptureProgressed,
1556         CaptureResultListener::onLogicalCameraCaptureCompleted,
1557         CaptureResultListener::onLogicalCameraCaptureFailed,
1558         CaptureResultListener::onCaptureSequenceCompleted,
1559         CaptureResultListener::onCaptureSequenceAborted,
1560         CaptureResultListener::onCaptureBufferLost
1561     };
1562 
1563     ACameraIdList* mCameraIdList = nullptr;
1564     ACameraDevice* mDevice = nullptr;
1565     AImageReader* mImgReader = nullptr;
1566     ANativeWindow* mImgReaderAnw = nullptr;
1567     ANativeWindow* mPreviewAnw = nullptr;
1568     ACameraManager* mCameraManager = nullptr;
1569     ACaptureSessionOutputContainer* mOutputs = nullptr;
1570     ACaptureSessionOutput* mPreviewOutput = nullptr;
1571     ACaptureSessionOutput* mImgReaderOutput = nullptr;
1572     ACameraCaptureSession* mSession = nullptr;
1573     ACaptureRequest* mPreviewRequest = nullptr;
1574     ACaptureRequest* mStillRequest = nullptr;
1575     ACameraOutputTarget* mReqPreviewOutput = nullptr;
1576     ACameraOutputTarget* mReqImgReaderOutput = nullptr;
1577     const char* mCameraId;
1578 
1579     bool mMgrInited = false; // cameraId, serviceListener
1580     bool mImgReaderInited = false;
1581     bool mPreviewInited = false;
1582 };
1583 
throwAssertionError(JNIEnv * env,const char * message)1584 jint throwAssertionError(JNIEnv* env, const char* message)
1585 {
1586     jclass assertionClass;
1587     const char* className = "junit/framework/AssertionFailedError";
1588 
1589     assertionClass = env->FindClass(className);
1590     if (assertionClass == nullptr) {
1591         ALOGE("Native throw error: cannot find class %s", className);
1592         return -1;
1593     }
1594     return env->ThrowNew(assertionClass, message);
1595 }
1596 
1597 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)1598 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1599 testCameraManagerGetAndCloseNative(
1600         JNIEnv* env, jclass /*clazz*/) {
1601     bool pass = false;
1602     ALOGV("%s", __FUNCTION__);
1603     ACameraManager* cameraManager2 = nullptr;
1604     ACameraManager* cameraManager3 = nullptr;
1605     ACameraManager* cameraManager4 = nullptr;
1606     camera_status_t ret = ACAMERA_OK;
1607     ACameraManager* cameraManager = ACameraManager_create();
1608     if (cameraManager == nullptr) {
1609         LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
1610         goto cleanup;
1611     }
1612     ACameraManager_delete(cameraManager);
1613     cameraManager = nullptr;
1614 
1615     // Test get/close multiple instances
1616     cameraManager = ACameraManager_create();
1617     cameraManager2 = ACameraManager_create();
1618     if (cameraManager2 == nullptr) {
1619         LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
1620         goto cleanup;
1621     }
1622     ACameraManager_delete(cameraManager);
1623     cameraManager = nullptr;
1624     cameraManager3 = ACameraManager_create();
1625     if (cameraManager3 == nullptr) {
1626         LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
1627         goto cleanup;
1628     }
1629     cameraManager4 = ACameraManager_create();
1630         if (cameraManager4 == nullptr) {
1631         LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
1632         goto cleanup;
1633     }
1634     ACameraManager_delete(cameraManager3);
1635     ACameraManager_delete(cameraManager2);
1636     ACameraManager_delete(cameraManager4);
1637 
1638     pass = true;
1639 cleanup:
1640     if (cameraManager) {
1641         ACameraManager_delete(cameraManager);
1642     }
1643     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1644     if (!pass) {
1645         throwAssertionError(env, errorString);
1646     }
1647     return pass;
1648 }
1649 
1650 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)1651 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1652 testCameraManagerGetCameraIdsNative(
1653         JNIEnv* env, jclass /*clazz*/) {
1654     ALOGV("%s", __FUNCTION__);
1655     bool pass = false;
1656     ACameraManager* mgr = ACameraManager_create();
1657     ACameraIdList *cameraIdList = nullptr;
1658     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1659     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1660         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1661                 ret, cameraIdList);
1662         goto cleanup;
1663     }
1664     ALOGI("Number of cameras: %d", cameraIdList->numCameras);
1665     for (int i = 0; i < cameraIdList->numCameras; i++) {
1666         ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
1667     }
1668     ACameraManager_deleteCameraIdList(cameraIdList);
1669     cameraIdList = nullptr;
1670 
1671     pass = true;
1672 cleanup:
1673     if (mgr) {
1674         ACameraManager_delete(mgr);
1675     }
1676     if (cameraIdList) {
1677         ACameraManager_deleteCameraIdList(cameraIdList);
1678     }
1679     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
1680     if (!pass) {
1681         throwAssertionError(env, errorString);
1682     }
1683     return pass;
1684 }
1685 
1686 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)1687 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1688 testCameraManagerAvailabilityCallbackNative(
1689         JNIEnv* env, jclass /*clazz*/) {
1690     ALOGV("%s", __FUNCTION__);
1691     bool pass = false;
1692     ACameraManager* mgr = ACameraManager_create();
1693     ACameraIdList *cameraIdList = nullptr;
1694     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1695     int numCameras = cameraIdList->numCameras;
1696     CameraServiceListener listener;
1697     ACameraManager_AvailabilityCallbacks cbs {
1698             &listener,
1699             CameraServiceListener::onAvailable,
1700             CameraServiceListener::onUnavailable};
1701     ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
1702     if (ret != ACAMERA_OK) {
1703         LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
1704         goto cleanup;
1705     }
1706     sleep(1); // sleep a second to give some time for callbacks to happen
1707 
1708     // Should at least get onAvailable for each camera once
1709     if (listener.getAvailableCount() < numCameras) {
1710         LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
1711                 numCameras, listener.getAvailableCount());
1712         goto cleanup;
1713     }
1714 
1715     ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
1716     if (ret != ACAMERA_OK) {
1717         LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
1718         goto cleanup;
1719     }
1720     pass = true;
1721 cleanup:
1722     if (cameraIdList) {
1723         ACameraManager_deleteCameraIdList(cameraIdList);
1724     }
1725     if (mgr) {
1726         ACameraManager_delete(mgr);
1727     }
1728     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1729     if (!pass) {
1730         throwAssertionError(env, errorString);
1731     }
1732     return pass;
1733 }
1734 
1735 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)1736 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1737 testCameraManagerCharacteristicsNative(
1738         JNIEnv* env, jclass /*clazz*/) {
1739     ALOGV("%s", __FUNCTION__);
1740     bool pass = false;
1741     ACameraManager* mgr = ACameraManager_create();
1742     ACameraIdList *cameraIdList = nullptr;
1743     ACameraMetadata* chars = nullptr;
1744     ACameraMetadata* copy = nullptr;
1745     int numCameras = 0;
1746     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1747     if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1748         LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1749                 ret, cameraIdList);
1750         goto cleanup;
1751     }
1752     numCameras = cameraIdList->numCameras;
1753 
1754     for (int i = 0; i < numCameras; i++) {
1755         ret = ACameraManager_getCameraCharacteristics(
1756                 mgr, cameraIdList->cameraIds[i], &chars);
1757         if (ret != ACAMERA_OK) {
1758             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1759             goto cleanup;
1760         }
1761 
1762         int32_t numTags = 0;
1763         const uint32_t* tags = nullptr;
1764         ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
1765         if (ret != ACAMERA_OK) {
1766             LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
1767             goto cleanup;
1768         }
1769 
1770         for (int tid = 0; tid < numTags; tid++) {
1771             uint32_t tagId = tags[tid];
1772             ALOGV("%s camera characteristics contains key %u", __FUNCTION__, tagId);
1773             uint32_t sectionId = tagId >> 16;
1774             if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
1775                 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
1776                 goto cleanup;
1777             }
1778         }
1779 
1780         ACameraMetadata_const_entry entry;
1781         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
1782         if (ret != ACAMERA_OK) {
1783             LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
1784             goto cleanup;
1785         }
1786 
1787         // Check the entry is actually legit
1788         if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
1789                 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
1790             LOG_ERROR(errorString,
1791                     "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
1792                     "type %d (expected %d), data %p (expected not null)",
1793                     entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
1794                     entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
1795             goto cleanup;
1796         }
1797         // All camera supports BC except depth only cameras
1798         bool supportBC = false, supportDepth = false;
1799         for (uint32_t i = 0; i < entry.count; i++) {
1800             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1801                 supportBC = true;
1802             }
1803             if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
1804                 supportDepth = true;
1805             }
1806         }
1807         if (!(supportBC || supportDepth)) {
1808             LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
1809                     cameraIdList->cameraIds[i]);
1810             goto cleanup;
1811         }
1812 
1813         // Check copy works
1814         copy = ACameraMetadata_copy(chars);
1815 
1816         // Compare copy with original
1817         ACameraMetadata_const_entry entryCopy;
1818         ret = ACameraMetadata_getConstEntry(
1819                 copy, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entryCopy);
1820         if (ret != ACAMERA_OK) {
1821             LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
1822             goto cleanup;
1823         }
1824         for (uint32_t i = 0; i < entry.count; i++) {
1825             if (entry.data.u8[i] != entryCopy.data.u8[i]) {
1826                 LOG_ERROR(errorString,
1827                     "Copy of available capability key[%d]: %d mismatches original %d",
1828                     i, entryCopy.data.u8[i], entry.data.u8[i]);
1829                 goto cleanup;
1830             }
1831         }
1832 
1833         // Check get unknown value fails
1834         uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
1835         ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
1836         if (ret == ACAMERA_OK) {
1837             LOG_ERROR(errorString, "Error: get unknown tag should fail!");
1838             goto cleanup;
1839         }
1840 
1841         ACameraMetadata_free(chars);
1842         ACameraMetadata_free(copy);
1843         chars = nullptr;
1844         copy = nullptr;
1845     }
1846 
1847     pass = true;
1848 cleanup:
1849     if (chars) {
1850         ACameraMetadata_free(chars);
1851     }
1852     if (copy) {
1853         ACameraMetadata_free(copy);
1854     }
1855     ACameraManager_deleteCameraIdList(cameraIdList);
1856     ACameraManager_delete(mgr);
1857     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1858     if (!pass) {
1859         throwAssertionError(env, errorString);
1860     }
1861     return pass;
1862 }
1863 
1864 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass)1865 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1866 testCameraDeviceOpenAndCloseNative(
1867         JNIEnv* env, jclass /*clazz*/) {
1868     ALOGV("%s", __FUNCTION__);
1869     int numCameras = 0;
1870     bool pass = false;
1871     PreviewTestCase testCase;
1872 
1873     camera_status_t ret = testCase.initWithErrorLog();
1874     if (ret != ACAMERA_OK) {
1875         // Don't log error here. testcase did it
1876         goto cleanup;
1877     }
1878 
1879     numCameras = testCase.getNumCameras();
1880     if (numCameras < 0) {
1881         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1882         goto cleanup;
1883     }
1884 
1885     for (int i = 0; i < numCameras; i++) {
1886         const char* cameraId = testCase.getCameraId(i);
1887         if (cameraId == nullptr) {
1888             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1889             goto cleanup;
1890         }
1891 
1892         ret = testCase.openCamera(cameraId);
1893         if (ret != ACAMERA_OK) {
1894             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1895             goto cleanup;
1896         }
1897 
1898         usleep(100000); // sleep to give some time for callbacks to happen
1899 
1900         if (testCase.isCameraAvailable(cameraId)) {
1901             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1902             goto cleanup;
1903         }
1904 
1905         ret = testCase.closeCamera();
1906         if (ret != ACAMERA_OK) {
1907             LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
1908             goto cleanup;
1909         }
1910 
1911         usleep(100000); // sleep to give some time for callbacks to happen
1912 
1913         if (!testCase.isCameraAvailable(cameraId)) {
1914             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1915             goto cleanup;
1916         }
1917     }
1918 
1919     ret = testCase.deInit();
1920     if (ret != ACAMERA_OK) {
1921         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1922         goto cleanup;
1923     }
1924 
1925     pass = true;
1926 cleanup:
1927     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1928     if (!pass) {
1929         throwAssertionError(env, errorString);
1930     }
1931     return pass;
1932 }
1933 
1934 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass)1935 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1936 testCameraDeviceCreateCaptureRequestNative(
1937         JNIEnv* env, jclass /*clazz*/) {
1938     ALOGV("%s", __FUNCTION__);
1939     bool pass = false;
1940     ACameraManager* mgr = ACameraManager_create();
1941     ACameraIdList* cameraIdList = nullptr;
1942     ACameraDevice* device = nullptr;
1943     ACaptureRequest* request = nullptr;
1944     ACameraMetadata* chars = nullptr;
1945     camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1946 
1947     int numCameras = cameraIdList->numCameras;
1948     for (int i = 0; i < numCameras; i++) {
1949         CameraDeviceListener deviceListener;
1950         const char* cameraId = cameraIdList->cameraIds[i];
1951         ACameraDevice_StateCallbacks deviceCb {
1952             &deviceListener,
1953             CameraDeviceListener::onDisconnected,
1954             CameraDeviceListener::onError
1955         };
1956         ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
1957         if (ret != ACAMERA_OK) {
1958             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1959             goto cleanup;
1960         }
1961 
1962         ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
1963         if (ret != ACAMERA_OK || chars == nullptr) {
1964             LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
1965                     cameraId, ret, chars);
1966             goto cleanup;
1967         }
1968         StaticInfo staticInfo(chars);
1969 
1970         for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
1971             ACameraDevice_request_template templateId =
1972                     static_cast<ACameraDevice_request_template>(t);
1973             ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
1974             if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
1975                 // template not supported. skip
1976                 continue;
1977             }
1978 
1979             if (ret != ACAMERA_OK) {
1980                 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
1981                 goto cleanup;
1982             }
1983 
1984             int32_t numTags = 0;
1985             const uint32_t* tags = nullptr;
1986             ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
1987             if (ret != ACAMERA_OK) {
1988                 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
1989                 goto cleanup;
1990             }
1991 
1992             for (int tid = 0; tid < numTags; tid++) {
1993                 uint32_t tagId = tags[tid];
1994                 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
1995                 uint32_t sectionId = tagId >> 16;
1996                 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
1997                     LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
1998                     goto cleanup;
1999                 }
2000             }
2001 
2002             void* context = nullptr;
2003             ret = ACaptureRequest_getUserContext(request, &context);
2004             if (ret != ACAMERA_OK) {
2005                 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2006                 goto cleanup;
2007             }
2008             if (context != nullptr) {
2009                 LOG_ERROR(errorString, "Capture request context is not null: %p", context);
2010                 goto cleanup;
2011             }
2012 
2013             intptr_t magic_num = 0xBEEF;
2014             ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
2015             if (ret != ACAMERA_OK) {
2016                 LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
2017                 goto cleanup;
2018             }
2019 
2020             ret = ACaptureRequest_getUserContext(request, &context);
2021             if (ret != ACAMERA_OK) {
2022                 LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
2023                 goto cleanup;
2024             }
2025             if (context != (void*) magic_num) {
2026                 LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
2027                 goto cleanup;
2028             }
2029 
2030             // try get/set capture request fields
2031             ACameraMetadata_const_entry entry;
2032             ret = ACaptureRequest_getConstEntry_physicalCamera(request, nullptr,
2033                     ACAMERA_CONTROL_AE_MODE, &entry);
2034             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2035                 LOG_ERROR(errorString, "Get AE mode key for null physical id should fail. ret %d",
2036                         ret);
2037                 goto cleanup;
2038             }
2039             ret = ACaptureRequest_getConstEntry_physicalCamera(request, cameraId,
2040                     ACAMERA_CONTROL_AE_MODE, &entry);
2041             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2042                 LOG_ERROR(errorString, "Get AE mode key for physical id should fail. ret %d",
2043                         ret);
2044                 goto cleanup;
2045             }
2046             ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
2047             if (ret != ACAMERA_OK) {
2048                 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2049                 goto cleanup;
2050             }
2051 
2052             if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
2053                     entry.count != 1) {
2054                 LOG_ERROR(errorString,
2055                         "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
2056                         "count %d (expect %d)",
2057                         entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
2058                         entry.count, 1);
2059                 goto cleanup;
2060             }
2061             if (t == TEMPLATE_MANUAL) {
2062                 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
2063                     LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
2064                             entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
2065                     goto cleanup;
2066                 }
2067                 // try set AE_MODE_ON
2068                 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
2069                 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2070                         request, nullptr, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2071                 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2072                     LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2073                             "fail. ret %d", cameraId, ret);
2074                     goto cleanup;
2075                 }
2076                 ret = ACaptureRequest_setEntry_physicalCamera_u8(
2077                         request, cameraId, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2078                 if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2079                     LOG_ERROR(errorString, "Error: camera %s setEntry_physicalCamera_u8 should "
2080                             "fail. ret %d", cameraId, ret);
2081                     goto cleanup;
2082                 }
2083                 ret = ACaptureRequest_setEntry_u8(
2084                         request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2085                 if (ret != ACAMERA_OK) {
2086                     LOG_ERROR(errorString,
2087                             "Error: Camera %s template %d: update AE mode key fail. ret %d",
2088                             cameraId, t, ret);
2089                     goto cleanup;
2090                 }
2091                 ret = ACaptureRequest_getConstEntry(
2092                         request, ACAMERA_CONTROL_AE_MODE, &entry);
2093                 if (ret != ACAMERA_OK) {
2094                     LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2095                     goto cleanup;
2096                 }
2097                 if (entry.data.u8[0] != aeMode) {
2098                     LOG_ERROR(errorString,
2099                             "Error: AE mode key is not updated. expect %d but get %d",
2100                             aeMode, entry.data.u8[0]);
2101                     goto cleanup;
2102                 }
2103             } else {
2104                 if (staticInfo.isColorOutputSupported()) {
2105                     if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
2106                         LOG_ERROR(errorString,
2107                                 "Error: Template %d has wrong AE mode %d (expect %d)",
2108                                 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
2109                         goto cleanup;
2110                     }
2111                     // try set AE_MODE_OFF
2112                     if (staticInfo.isCapabilitySupported(
2113                             ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
2114                         uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
2115                         ret = ACaptureRequest_setEntry_u8(
2116                                 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
2117                         if (ret != ACAMERA_OK) {
2118                             LOG_ERROR(errorString,
2119                                     "Error: Camera %s template %d: update AE mode key fail. ret %d",
2120                                     cameraId, t, ret);
2121                             goto cleanup;
2122                         }
2123                         ret = ACaptureRequest_getConstEntry(
2124                                 request, ACAMERA_CONTROL_AE_MODE, &entry);
2125                         if (ret != ACAMERA_OK) {
2126                             LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
2127                             goto cleanup;
2128                         }
2129                         if (entry.data.u8[0] != aeMode) {
2130                             LOG_ERROR(errorString,
2131                                     "Error: AE mode key is not updated. expect %d but get %d",
2132                                     aeMode, entry.data.u8[0]);
2133                             goto cleanup;
2134                         }
2135                     }
2136                 }
2137             }
2138             ACaptureRequest_free(request);
2139             request = nullptr;
2140         }
2141 
2142         ACameraMetadata_free(chars);
2143         chars = nullptr;
2144         ACameraDevice_close(device);
2145         device = nullptr;
2146     }
2147 
2148     pass = true;
2149 cleanup:
2150     if (cameraIdList) {
2151         ACameraManager_deleteCameraIdList(cameraIdList);
2152     }
2153     if (request) {
2154         ACaptureRequest_free(request);
2155     }
2156     if (chars) {
2157         ACameraMetadata_free(chars);
2158     }
2159     if (device) {
2160         ACameraDevice_close(device);
2161     }
2162     if (mgr) {
2163         ACameraManager_delete(mgr);
2164     }
2165     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2166     if (!pass) {
2167         throwAssertionError(env, errorString);
2168     }
2169     return pass;
2170 }
2171 
2172 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface)2173 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2174 testCameraDeviceSessionOpenAndCloseNative(
2175         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
2176     ALOGV("%s", __FUNCTION__);
2177     int numCameras = 0;
2178     bool pass = false;
2179     PreviewTestCase testCase;
2180 
2181     camera_status_t ret = testCase.initWithErrorLog();
2182     if (ret != ACAMERA_OK) {
2183         // Don't log error here. testcase did it
2184         goto cleanup;
2185     }
2186 
2187     numCameras = testCase.getNumCameras();
2188     if (numCameras < 0) {
2189         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2190         goto cleanup;
2191     }
2192 
2193     for (int i = 0; i < numCameras; i++) {
2194         const char* cameraId = testCase.getCameraId(i);
2195         if (cameraId == nullptr) {
2196             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2197             goto cleanup;
2198         }
2199 
2200         {
2201             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2202             StaticInfo staticInfo(chars);
2203             if (!staticInfo.isColorOutputSupported()) {
2204                 ALOGI("%s: camera %s does not support color output. skipping",
2205                         __FUNCTION__, cameraId);
2206                 ACameraMetadata_free(chars);
2207                 continue;
2208             }
2209             ACameraMetadata_free(chars);
2210         }
2211 
2212         ret = testCase.openCamera(cameraId);
2213         if (ret != ACAMERA_OK) {
2214             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2215             goto cleanup;
2216         }
2217 
2218         usleep(100000); // sleep to give some time for callbacks to happen
2219 
2220         if (testCase.isCameraAvailable(cameraId)) {
2221             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2222             goto cleanup;
2223         }
2224 
2225         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2226         if (previewAnw == nullptr) {
2227             LOG_ERROR(errorString, "Null ANW from preview surface!");
2228             goto cleanup;
2229         }
2230 
2231         CaptureSessionListener* sessionListener = testCase.getSessionListener();
2232         if (sessionListener == nullptr) {
2233             LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
2234             goto cleanup;
2235         }
2236 
2237         // Try open/close session multiple times
2238         for (int j = 0; j < 5; j++) {
2239             ret = testCase.createCaptureSessionWithLog();
2240             if (ret != ACAMERA_OK) {
2241                 // Don't log error here. testcase did it
2242                 goto cleanup;
2243             }
2244 
2245             usleep(100000); // sleep to give some time for callbacks to happen
2246 
2247             if (!sessionListener->isIdle()) {
2248                 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
2249                         cameraId);
2250                 goto cleanup;
2251             }
2252 
2253             testCase.closeSession();
2254 
2255             usleep(100000); // sleep to give some time for callbacks to happen
2256             if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2257                 LOG_ERROR(errorString,
2258                         "Session for camera %s close error. isClosde %d close count %d",
2259                         cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2260                 goto cleanup;
2261             }
2262             sessionListener->reset();
2263         }
2264 
2265         // Try open/close really fast
2266         ret = testCase.createCaptureSessionWithLog();
2267         if (ret != ACAMERA_OK) {
2268             LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
2269                     cameraId, ret);
2270             goto cleanup;
2271         }
2272         testCase.closeSession();
2273         usleep(100000); // sleep to give some time for callbacks to happen
2274         if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
2275             LOG_ERROR(errorString,
2276                     "Session for camera %s close error. isClosde %d close count %d",
2277                     cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
2278             goto cleanup;
2279         }
2280 
2281         ret = testCase.resetWithErrorLog();
2282         if (ret != ACAMERA_OK) {
2283             // Don't log error here. testcase did it
2284             goto cleanup;
2285         }
2286 
2287         usleep(100000); // sleep to give some time for callbacks to happen
2288 
2289         if (!testCase.isCameraAvailable(cameraId)) {
2290             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2291             goto cleanup;
2292         }
2293     }
2294 
2295     ret = testCase.deInit();
2296     if (ret != ACAMERA_OK) {
2297         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2298         goto cleanup;
2299     }
2300 
2301     pass = true;
2302 cleanup:
2303     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2304     if (!pass) {
2305         throwAssertionError(env, errorString);
2306     }
2307     return pass;
2308 }
2309 
2310 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSharedOutputUpdate(JNIEnv * env,jclass,jobject jPreviewSurface,jobject jSharedSurface)2311 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2312 testCameraDeviceSharedOutputUpdate(
2313         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface, jobject jSharedSurface) {
2314     ALOGV("%s", __FUNCTION__);
2315     int numCameras = 0;
2316     bool pass = false;
2317     PreviewTestCase testCase;
2318     int sequenceId = -1;
2319     int64_t lastFrameNumber = 0;
2320     bool frameArrived = false;
2321     ANativeWindow* previewAnw = nullptr;
2322     ANativeWindow* sharedAnw = ANativeWindow_fromSurface(env, jSharedSurface);
2323     ACaptureRequest* updatedRequest = nullptr;
2324     ACameraOutputTarget* reqPreviewOutput = nullptr;
2325     ACameraOutputTarget* reqSharedOutput = nullptr;
2326     ACaptureSessionOutput *previewOutput = nullptr;
2327     uint32_t timeoutSec = 1;
2328     uint32_t runPreviewSec = 2;
2329 
2330     camera_status_t ret = testCase.initWithErrorLog();
2331     if (ret != ACAMERA_OK) {
2332         // Don't log error here. testcase did it
2333         goto cleanup;
2334     }
2335 
2336     numCameras = testCase.getNumCameras();
2337     if (numCameras < 0) {
2338         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2339         goto cleanup;
2340     }
2341 
2342     for (int i = 0; i < numCameras; i++) {
2343         const char* cameraId = testCase.getCameraId(i);
2344         if (cameraId == nullptr) {
2345             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2346             goto cleanup;
2347         }
2348 
2349         {
2350             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2351             StaticInfo staticInfo(chars);
2352             if (!staticInfo.isColorOutputSupported()) {
2353                 ALOGI("%s: camera %s does not support color output. skipping",
2354                         __FUNCTION__, cameraId);
2355                 ACameraMetadata_free(chars);
2356                 continue;
2357             }
2358             ACameraMetadata_free(chars);
2359         }
2360 
2361         ret = testCase.openCamera(cameraId);
2362         if (ret != ACAMERA_OK) {
2363             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2364             goto cleanup;
2365         }
2366 
2367         usleep(100000); // sleep to give some time for callbacks to happen
2368 
2369         if (testCase.isCameraAvailable(cameraId)) {
2370             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2371             goto cleanup;
2372         }
2373 
2374         previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2375         if (previewAnw == nullptr) {
2376             LOG_ERROR(errorString, "Null ANW from preview surface!");
2377             goto cleanup;
2378         }
2379 
2380         ret = testCase.createCaptureSessionWithLog(true);
2381         if (ret != ACAMERA_OK) {
2382             // Don't log error here. testcase did it
2383             goto cleanup;
2384         }
2385 
2386         ret = testCase.createRequestsWithErrorLog();
2387         if (ret != ACAMERA_OK) {
2388             // Don't log error here. testcase did it
2389             goto cleanup;
2390         }
2391 
2392         ret = testCase.startPreview();
2393         if (ret != ACAMERA_OK) {
2394             LOG_ERROR(errorString, "Start preview failed!");
2395             goto cleanup;
2396         }
2397 
2398         sleep(runPreviewSec);
2399 
2400         previewOutput = testCase.getPreviewOutput();
2401         //Try some bad input
2402         ret = ACaptureSessionSharedOutput_add(previewOutput, previewAnw);
2403         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2404             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add should return invalid "
2405                     "parameter! %d", ret);
2406             goto cleanup;
2407         }
2408 
2409         ret = ACaptureSessionSharedOutput_remove(previewOutput, previewAnw);
2410         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2411             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove should return invalid "
2412                     "parameter! %d", ret);
2413             goto cleanup;
2414         }
2415 
2416         //Now try with valid input
2417         ret = ACaptureSessionSharedOutput_add(previewOutput, sharedAnw);
2418         if (ret != ACAMERA_OK) {
2419             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_add failed!")
2420             goto cleanup;
2421         }
2422 
2423         ret = testCase.updateOutput(env, previewOutput);
2424         if (ret != ACAMERA_OK) {
2425             LOG_ERROR(errorString, "Failed to update output configuration!")
2426             goto cleanup;
2427         }
2428 
2429         ret = ACameraDevice_createCaptureRequest(
2430                 testCase.getCameraDevice(), TEMPLATE_PREVIEW, &updatedRequest);
2431         if (ret != ACAMERA_OK) {
2432             LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
2433                     cameraId, ret);
2434             goto cleanup;
2435         }
2436 
2437         ret = ACameraOutputTarget_create(previewAnw, &reqPreviewOutput);
2438         if (ret != ACAMERA_OK) {
2439             LOG_ERROR(errorString,
2440                     "Camera %s create request preview output target failed. ret %d",
2441                     cameraId, ret);
2442             goto cleanup;
2443         }
2444 
2445         ret = ACaptureRequest_addTarget(updatedRequest, reqPreviewOutput);
2446         if (ret != ACAMERA_OK) {
2447             LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2448                     cameraId, ret);
2449             goto cleanup;
2450         }
2451 
2452         ret = ACameraOutputTarget_create(sharedAnw, &reqSharedOutput);
2453         if (ret != ACAMERA_OK) {
2454             LOG_ERROR(errorString,
2455                     "Camera %s create request preview output target failed. ret %d",
2456                     cameraId, ret);
2457             goto cleanup;
2458         }
2459 
2460         ret = ACaptureRequest_addTarget(updatedRequest, reqSharedOutput);
2461         if (ret != ACAMERA_OK) {
2462             LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
2463                     cameraId, ret);
2464             goto cleanup;
2465         }
2466 
2467         ret = testCase.updateRepeatingRequest(updatedRequest, &sequenceId);
2468         if (ret != ACAMERA_OK) {
2469             LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2470                     cameraId, ret);
2471             goto cleanup;
2472         }
2473 
2474         sleep(runPreviewSec);
2475 
2476         ret = ACaptureSessionSharedOutput_remove(previewOutput, sharedAnw);
2477         if (ret != ACAMERA_OK) {
2478             LOG_ERROR(errorString, "ACaptureSessionSharedOutput_remove failed!");
2479             goto cleanup;
2480         }
2481 
2482         //Try removing shared output which still has pending camera requests
2483         ret = testCase.updateOutput(env, previewOutput);
2484         if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2485             LOG_ERROR(errorString, "updateOutput should fail!");
2486             goto cleanup;
2487         }
2488 
2489         //Remove the shared output correctly by updating the repeating request
2490         //first
2491         ret = ACaptureRequest_removeTarget(updatedRequest, reqSharedOutput);
2492         if (ret != ACAMERA_OK) {
2493             LOG_ERROR(errorString, "Camera %s remove target output failed. ret %d",
2494                     cameraId, ret);
2495             goto cleanup;
2496         }
2497 
2498         ret = testCase.updateRepeatingRequest(updatedRequest);
2499         if (ret != ACAMERA_OK) {
2500             LOG_ERROR(errorString, "Camera %s failed to update repeated request. ret %d",
2501                     cameraId, ret);
2502             goto cleanup;
2503         }
2504 
2505         //Then wait for all old requests to flush
2506         lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
2507         if (lastFrameNumber < 0) {
2508             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
2509                     cameraId);
2510             goto cleanup;
2511         }
2512 
2513         frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
2514         if (!frameArrived) {
2515             LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
2516                     cameraId);
2517             goto cleanup;
2518         }
2519 
2520         ret = testCase.updateOutput(env, previewOutput);
2521         if (ret != ACAMERA_OK) {
2522             LOG_ERROR(errorString, "updateOutput failed!");
2523             goto cleanup;
2524         }
2525 
2526         sleep(runPreviewSec);
2527 
2528         ret = testCase.resetWithErrorLog();
2529         if (ret != ACAMERA_OK) {
2530             // Don't log error here. testcase did it
2531             goto cleanup;
2532         }
2533 
2534         usleep(100000); // sleep to give some time for callbacks to happen
2535 
2536         if (!testCase.isCameraAvailable(cameraId)) {
2537             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2538             goto cleanup;
2539         }
2540     }
2541 
2542     ret = testCase.deInit();
2543     if (ret != ACAMERA_OK) {
2544         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2545         goto cleanup;
2546     }
2547 
2548     pass = true;
2549 
2550 cleanup:
2551 
2552     if (updatedRequest != nullptr) {
2553         ACaptureRequest_free(updatedRequest);
2554         updatedRequest = nullptr;
2555     }
2556 
2557     if (reqPreviewOutput != nullptr) {
2558         ACameraOutputTarget_free(reqPreviewOutput);
2559         reqPreviewOutput = nullptr;
2560     }
2561 
2562     if (reqSharedOutput != nullptr) {
2563         ACameraOutputTarget_free(reqSharedOutput);
2564         reqSharedOutput = nullptr;
2565     }
2566 
2567     if (sharedAnw) {
2568         ANativeWindow_release(sharedAnw);
2569         sharedAnw = nullptr;
2570     }
2571 
2572     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2573     if (!pass) {
2574         throwAssertionError(env, errorString);
2575     }
2576     return pass;
2577 }
2578 
2579 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass,jobject jPreviewSurface)2580 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2581 testCameraDeviceSimplePreviewNative(
2582         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
2583     ALOGV("%s", __FUNCTION__);
2584     int numCameras = 0;
2585     bool pass = false;
2586     PreviewTestCase testCase;
2587 
2588     camera_status_t ret = testCase.initWithErrorLog();
2589     if (ret != ACAMERA_OK) {
2590         // Don't log error here. testcase did it
2591         goto cleanup;
2592     }
2593 
2594     numCameras = testCase.getNumCameras();
2595     if (numCameras < 0) {
2596         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2597         goto cleanup;
2598     }
2599 
2600     for (int i = 0; i < numCameras; i++) {
2601         const char* cameraId = testCase.getCameraId(i);
2602         if (cameraId == nullptr) {
2603             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2604             goto cleanup;
2605         }
2606 
2607         {
2608             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
2609             StaticInfo staticInfo(chars);
2610             if (!staticInfo.isColorOutputSupported()) {
2611                 ALOGI("%s: camera %s does not support color output. skipping",
2612                         __FUNCTION__, cameraId);
2613                 ACameraMetadata_free(chars);
2614                 continue;
2615             }
2616             ACameraMetadata_free(chars);
2617         }
2618 
2619         ret = testCase.openCamera(cameraId);
2620         if (ret != ACAMERA_OK) {
2621             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2622             goto cleanup;
2623         }
2624 
2625         usleep(100000); // sleep to give some time for callbacks to happen
2626 
2627         if (testCase.isCameraAvailable(cameraId)) {
2628             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2629             goto cleanup;
2630         }
2631 
2632         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2633         if (previewAnw == nullptr) {
2634             LOG_ERROR(errorString, "Null ANW from preview surface!");
2635             goto cleanup;
2636         }
2637 
2638         ret = testCase.createCaptureSessionWithLog();
2639         if (ret != ACAMERA_OK) {
2640             // Don't log error here. testcase did it
2641             goto cleanup;
2642         }
2643 
2644         ret = testCase.createRequestsWithErrorLog();
2645         if (ret != ACAMERA_OK) {
2646             // Don't log error here. testcase did it
2647             goto cleanup;
2648         }
2649 
2650         ret = testCase.startPreview();
2651         if (ret != ACAMERA_OK) {
2652             LOG_ERROR(errorString, "Start preview failed!");
2653             goto cleanup;
2654         }
2655 
2656         sleep(3);
2657 
2658         ret = testCase.resetWithErrorLog();
2659         if (ret != ACAMERA_OK) {
2660             // Don't log error here. testcase did it
2661             goto cleanup;
2662         }
2663 
2664         usleep(100000); // sleep to give some time for callbacks to happen
2665 
2666         if (!testCase.isCameraAvailable(cameraId)) {
2667             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2668             goto cleanup;
2669         }
2670     }
2671 
2672     ret = testCase.deInit();
2673     if (ret != ACAMERA_OK) {
2674         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2675         goto cleanup;
2676     }
2677 
2678     pass = true;
2679 cleanup:
2680     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2681     if (!pass) {
2682         throwAssertionError(env, errorString);
2683     }
2684     return pass;
2685 }
2686 
2687 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDevicePreviewWithSessionParametersNative(JNIEnv * env,jclass,jobject jPreviewSurface)2688 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
2689 testCameraDevicePreviewWithSessionParametersNative(
2690         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
2691     ALOGV("%s", __FUNCTION__);
2692     int numCameras = 0;
2693     bool pass = false;
2694     ACameraManager* mgr = ACameraManager_create();
2695     ACameraMetadata* chars = nullptr;
2696     PreviewTestCase testCase;
2697 
2698     camera_status_t ret = testCase.initWithErrorLog();
2699     if (ret != ACAMERA_OK) {
2700         // Don't log error here. testcase did it
2701         goto cleanup;
2702     }
2703 
2704     numCameras = testCase.getNumCameras();
2705     if (numCameras < 0) {
2706         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2707         goto cleanup;
2708     }
2709 
2710     for (int i = 0; i < numCameras; i++) {
2711         const char* cameraId = testCase.getCameraId(i);
2712         if (cameraId == nullptr) {
2713             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2714             goto cleanup;
2715         }
2716 
2717         ret = ACameraManager_getCameraCharacteristics(
2718                 mgr, cameraId, &chars);
2719         if (ret != ACAMERA_OK) {
2720             LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
2721             goto cleanup;
2722         }
2723 
2724         StaticInfo staticInfo(chars);
2725         ACameraMetadata_const_entry sessionParamKeys{};
2726         ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_SESSION_KEYS,
2727                 &sessionParamKeys);
2728         if ((ret != ACAMERA_OK) || (sessionParamKeys.count == 0) ||
2729                 !staticInfo.isColorOutputSupported()) {
2730             ACameraMetadata_free(chars);
2731             chars = nullptr;
2732             continue;
2733         }
2734 
2735         ret = testCase.openCamera(cameraId);
2736         if (ret != ACAMERA_OK) {
2737             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2738             goto cleanup;
2739         }
2740 
2741         usleep(100000); // sleep to give some time for callbacks to happen
2742 
2743         if (testCase.isCameraAvailable(cameraId)) {
2744             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2745             goto cleanup;
2746         }
2747 
2748         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2749         if (previewAnw == nullptr) {
2750             LOG_ERROR(errorString, "Null ANW from preview surface!");
2751             goto cleanup;
2752         }
2753 
2754         ret = testCase.createRequestsWithErrorLog();
2755         if (ret != ACAMERA_OK) {
2756             // Don't log error here. testcase did it
2757             goto cleanup;
2758         }
2759 
2760         ACaptureRequest *previewRequest = nullptr;
2761         ret = testCase.getPreviewRequest(&previewRequest);
2762         if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
2763             LOG_ERROR(errorString, "Preview request query failed!");
2764             goto cleanup;
2765         }
2766 
2767         ret = testCase.createCaptureSessionWithLog(/*isPreviewShared*/ false, previewRequest);
2768         if (ret != ACAMERA_OK) {
2769             // Don't log error here. testcase did it
2770             goto cleanup;
2771         }
2772 
2773         ret = testCase.startPreview();
2774         if (ret != ACAMERA_OK) {
2775             LOG_ERROR(errorString, "Start preview failed!");
2776             goto cleanup;
2777         }
2778 
2779         sleep(3);
2780 
2781         ret = testCase.resetWithErrorLog();
2782         if (ret != ACAMERA_OK) {
2783             // Don't log error here. testcase did it
2784             goto cleanup;
2785         }
2786 
2787         usleep(100000); // sleep to give some time for callbacks to happen
2788 
2789         if (!testCase.isCameraAvailable(cameraId)) {
2790             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
2791             goto cleanup;
2792         }
2793 
2794         ACameraMetadata_free(chars);
2795         chars = nullptr;
2796     }
2797 
2798     ret = testCase.deInit();
2799     if (ret != ACAMERA_OK) {
2800         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
2801         goto cleanup;
2802     }
2803 
2804     pass = true;
2805 cleanup:
2806     if (chars) {
2807         ACameraMetadata_free(chars);
2808     }
2809     ACameraManager_delete(mgr);
2810     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
2811     if (!pass) {
2812         throwAssertionError(env, errorString);
2813     }
2814     return pass;
2815 }
2816 
nativeCameraDeviceLogicalPhysicalStreaming(JNIEnv * env,jobject jPreviewSurface,bool usePhysicalSettings)2817 bool nativeCameraDeviceLogicalPhysicalStreaming(
2818         JNIEnv* env, jobject jPreviewSurface, bool usePhysicalSettings) {
2819     const int NUM_TEST_IMAGES = 10;
2820     const int TEST_WIDTH  = 640;
2821     const int TEST_HEIGHT = 480;
2822     ALOGV("%s", __FUNCTION__);
2823     int numCameras = 0;
2824     bool pass = false;
2825     ACameraManager* mgr = ACameraManager_create();
2826     ACameraMetadata* chars = nullptr;
2827     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
2828     PreviewTestCase testCase;
2829     int64_t lastFrameNumber = 0;
2830     bool frameArrived = false;
2831     uint32_t timeoutSec = 1;
2832     uint32_t runPreviewSec = 2;
2833 
2834     camera_status_t ret = testCase.initWithErrorLog();
2835     if (ret != ACAMERA_OK) {
2836         // Don't log error here. testcase did it
2837         goto cleanup;
2838     }
2839 
2840     numCameras = testCase.getNumCameras();
2841     if (numCameras < 0) {
2842         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
2843         goto cleanup;
2844     }
2845 
2846     for (int i = 0; i < numCameras; i++) {
2847         const char* cameraId = testCase.getCameraId(i);
2848         if (cameraId == nullptr) {
2849             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
2850             goto cleanup;
2851         }
2852 
2853         if (chars != nullptr) {
2854             ACameraMetadata_free(chars);
2855             chars = nullptr;
2856         }
2857         chars = testCase.getCameraChars(i);
2858         if (chars == nullptr) {
2859             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
2860             goto cleanup;
2861         }
2862 
2863         size_t physicalCameraCnt = 0;
2864         const char *const* physicalCameraIds = nullptr;
2865         if (!ACameraMetadata_isLogicalMultiCamera(
2866                 chars, &physicalCameraCnt, &physicalCameraIds)) {
2867             continue;
2868         }
2869         if (physicalCameraCnt < 2) {
2870             LOG_ERROR(errorString, "Logical camera device %s only has %zu physical cameras",
2871                    cameraId, physicalCameraCnt);
2872             goto cleanup;
2873         }
2874 
2875         std::vector<const char*> candidateIds;
2876         for (size_t i = 0; i < physicalCameraCnt && candidateIds.size() < 2; i++) {
2877             ACameraMetadata* physicalChars = testCase.getCameraChars(physicalCameraIds[i]);
2878             if (physicalChars == nullptr) {
2879                 LOG_ERROR(errorString,
2880                         "Get camera %s characteristics failure", physicalCameraIds[i]);
2881                 goto cleanup;
2882             }
2883             StaticInfo info(physicalChars);
2884             bool testSizeSupported = info.isSizeSupportedForFormat(AIMAGE_FORMAT_YUV_420_888,
2885                     TEST_WIDTH, TEST_HEIGHT);
2886             ACameraMetadata_free(physicalChars);
2887             if (!testSizeSupported) {
2888                 continue;
2889             }
2890             candidateIds.push_back(physicalCameraIds[i]);
2891         }
2892         if (candidateIds.size() < 2) {
2893             continue;
2894         }
2895 
2896         // Check physical camera request keys
2897         if (usePhysicalSettings) {
2898             ACameraMetadata_const_entry entry;
2899             camera_status_t status = ACameraMetadata_getConstEntry(
2900                     chars, ACAMERA_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &entry);
2901             if (status == ACAMERA_ERROR_METADATA_NOT_FOUND) {
2902                 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
2903                 continue;
2904             } else if (status != ACAMERA_OK) {
2905                 // Do not log error here. testcase did it.
2906                 goto cleanup;
2907             } else if (entry.count == 0) {
2908                 // No supported PHYSICAL_CAMERA_REQUEST_KEYS, skip test
2909                 continue;
2910             }
2911         }
2912 
2913         ret = testCase.openCamera(cameraId);
2914         if (ret != ACAMERA_OK) {
2915             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
2916             goto cleanup;
2917         }
2918 
2919         usleep(100000); // sleep to give some time for callbacks to happen
2920 
2921         if (testCase.isCameraAvailable(cameraId)) {
2922             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
2923             goto cleanup;
2924         }
2925 
2926         std::vector<ImageReaderListener> readerListeners(2);
2927         std::vector<AImageReader_ImageListener> readerCbs;
2928         std::vector<AImageReader*> readers;
2929         std::vector<ANativeWindow*> readerAnws;
2930         std::vector<ACaptureSessionOutput*> readerSessionOutputs;
2931         std::vector<ACameraOutputTarget*> readerOutputs;
2932         for (size_t i = 0; i < 2; i++) {
2933             AImageReader_ImageListener readerCb {
2934                 &readerListeners[i],
2935                 ImageReaderListener::validateImageCb
2936             };
2937             readerCbs.push_back(readerCb);
2938 
2939             AImageReader* reader = nullptr;
2940             ANativeWindow* readerAnw = nullptr;
2941             ACaptureSessionOutput* readerSessionOutput = nullptr;
2942             ACameraOutputTarget* readerOutput = nullptr;
2943             mediaRet = testCase.initImageReaderWithErrorLog(
2944                     TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES,
2945                     &readerCb, &reader, &readerAnw);
2946             if (mediaRet != AMEDIA_OK) {
2947                 // Don't log error here. testcase did it
2948                 goto cleanup;
2949             }
2950 
2951             camera_status_t ret = ACaptureSessionPhysicalOutput_create(readerAnw,
2952                     candidateIds[i], &readerSessionOutput);
2953             if (ret != ACAMERA_OK || readerSessionOutput == nullptr) {
2954                 if (ret == ACAMERA_OK) {
2955                     ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
2956                 }
2957                 // Don't log error here. testcase did it
2958                 goto cleanup;
2959             }
2960 
2961             ret = ACameraOutputTarget_create(readerAnw, &readerOutput);
2962             if (ret != ACAMERA_OK) {
2963                 // Don't log error here. testcase did it
2964                 goto cleanup;
2965             }
2966 
2967             readers.push_back(reader);
2968             readerAnws.push_back(readerAnw);
2969             readerSessionOutputs.push_back(readerSessionOutput);
2970             readerOutputs.push_back(readerOutput);
2971         }
2972 
2973         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
2974         if (previewAnw == nullptr) {
2975             LOG_ERROR(errorString, "Null ANW from preview surface!");
2976             goto cleanup;
2977         }
2978 
2979         ret = testCase.createCaptureSessionWithLog(readerSessionOutputs, false /*isPreviewShared*/,
2980                 nullptr /*sessionParameters*/, false /*sessionConfigurationDefault*/);
2981         if (ret == ACAMERA_ERROR_UNSUPPORTED_OPERATION ||
2982                 ret == ACAMERA_ERROR_STREAM_CONFIGURE_FAIL) {
2983             // Camera device doesn't support the stream combination, skip the
2984             // current camera.
2985             testCase.closeCamera();
2986             testCase.resetCamera();
2987             continue;
2988         } else if (ret != ACAMERA_OK) {
2989             // Don't log error here. testcase did it
2990             goto cleanup;
2991         }
2992 
2993         if (usePhysicalSettings) {
2994             std::vector<const char*> twoNullStr = {nullptr, nullptr};
2995             ACameraIdList nullCameraIdList = {2, twoNullStr.data()};
2996             ret = testCase.createRequestsWithErrorLog(readerOutputs, &nullCameraIdList);
2997             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
2998                 LOG_ERROR(errorString, "Null physical camera ids must fail createCaptureRequest. "
2999                         "ret %d", ret);
3000                 goto cleanup;
3001             }
3002 
3003             std::string invalidId = "";
3004             std::vector<const char*> one0LengthStr = {invalidId.c_str()};
3005             ACameraIdList invalidCameraIdList = {1, one0LengthStr.data()};
3006             ret = testCase.createRequestsWithErrorLog(readerOutputs, &invalidCameraIdList);
3007             if (ret != ACAMERA_ERROR_INVALID_PARAMETER) {
3008                 LOG_ERROR(errorString, "zero-length physical camera ids must fail "
3009                         "createCaptureRequest. ret %d", ret);
3010                 goto cleanup;
3011             }
3012 
3013             ACameraIdList physicalCameraIdList = {2, candidateIds.data()};
3014             ret = testCase.createRequestsWithErrorLog(readerOutputs, &physicalCameraIdList);
3015         } else {
3016             ret = testCase.createRequestsWithErrorLog(readerOutputs);
3017         }
3018         if (ret != ACAMERA_OK) {
3019             // Don't log error here. testcase did it
3020             goto cleanup;
3021         }
3022 
3023         ACaptureRequest *previewRequest = nullptr;
3024         ret = testCase.getPreviewRequest(&previewRequest);
3025         if ((ret != ACAMERA_OK) || (previewRequest == nullptr)) {
3026             LOG_ERROR(errorString, "Preview request query failed!");
3027             goto cleanup;
3028         }
3029 
3030         int sequenceId = 0;
3031         ret = testCase.startPreview(&sequenceId, 2, candidateIds.data());
3032         if (ret != ACAMERA_OK) {
3033             LOG_ERROR(errorString, "Start preview failed!");
3034             goto cleanup;
3035         }
3036 
3037         sleep(runPreviewSec);
3038 
3039         ret = testCase.stopPreview();
3040         if (ret != ACAMERA_OK) {
3041             ALOGE("%s: stopPreview failed", __FUNCTION__);
3042             LOG_ERROR(errorString, "stopPreview failed!");
3043             goto cleanup;
3044         }
3045 
3046         //Then wait for all old requests to flush
3047         lastFrameNumber = testCase.getCaptureSequenceLastFrameNumber(sequenceId, timeoutSec);
3048         if (lastFrameNumber < 0) {
3049             LOG_ERROR(errorString, "Camera %s failed to acquire last frame number!",
3050                     cameraId);
3051             goto cleanup;
3052         }
3053 
3054         frameArrived = testCase.waitForFrameNumber(lastFrameNumber, timeoutSec);
3055         if (!frameArrived) {
3056             LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3057                     cameraId);
3058             goto cleanup;
3059         }
3060 
3061         ret = testCase.resetWithErrorLog();
3062         if (ret != ACAMERA_OK) {
3063             // Don't log error here. testcase did it
3064             goto cleanup;
3065         }
3066 
3067         usleep(100000); // sleep to give some time for callbacks to happen
3068 
3069         if (!testCase.isCameraAvailable(cameraId)) {
3070             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3071             goto cleanup;
3072         }
3073     }
3074 
3075     ret = testCase.deInit();
3076     if (ret != ACAMERA_OK) {
3077         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3078         goto cleanup;
3079     }
3080 
3081     pass = true;
3082 cleanup:
3083     if (chars) {
3084         ACameraMetadata_free(chars);
3085     }
3086     ACameraManager_delete(mgr);
3087     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3088     if (!pass) {
3089         throwAssertionError(env, errorString);
3090     }
3091     return pass;
3092 }
3093 
3094 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalStreamingNative(JNIEnv * env,jclass,jobject jPreviewSurface)3095 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3096 testCameraDeviceLogicalPhysicalStreamingNative(
3097         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
3098     return nativeCameraDeviceLogicalPhysicalStreaming(env,
3099             jPreviewSurface, false /*usePhysicalSettings*/);
3100 }
3101 
3102 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceLogicalPhysicalSettingsNative(JNIEnv * env,jclass,jobject jPreviewSurface)3103 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3104 testCameraDeviceLogicalPhysicalSettingsNative(
3105         JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
3106     return nativeCameraDeviceLogicalPhysicalStreaming(env,
3107             jPreviewSurface, true /*usePhysicalSettings*/);
3108 }
3109 
3110 
nativeImageReaderTestBase(JNIEnv * env,jstring jOutPath,jint format,AImageReader_ImageCallback cb)3111 bool nativeImageReaderTestBase(
3112         JNIEnv* env, jstring jOutPath, jint format, AImageReader_ImageCallback cb) {
3113     const int NUM_TEST_IMAGES = 10;
3114     const int TEST_WIDTH  = 640;
3115     const int TEST_HEIGHT = 480;
3116     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3117     int numCameras = 0;
3118     bool pass = false;
3119     PreviewTestCase testCase;
3120     ACameraMetadata* chars = nullptr;
3121 
3122     const char* outPath = (jOutPath == nullptr) ? nullptr :
3123             env->GetStringUTFChars(jOutPath, nullptr);
3124     if (outPath != nullptr) {
3125         ALOGI("%s: out path is %s", __FUNCTION__, outPath);
3126     }
3127 
3128     camera_status_t ret = testCase.initWithErrorLog();
3129     if (ret != ACAMERA_OK) {
3130         // Don't log error here. testcase did it
3131         goto cleanup;
3132     }
3133 
3134     numCameras = testCase.getNumCameras();
3135     if (numCameras < 0) {
3136         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3137         goto cleanup;
3138     }
3139 
3140     for (int i = 0; i < numCameras; i++) {
3141         const char* cameraId = testCase.getCameraId(i);
3142         if (cameraId == nullptr) {
3143             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3144             goto cleanup;
3145         }
3146 
3147         {
3148             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
3149             StaticInfo staticInfo(chars);
3150             if (!staticInfo.isColorOutputSupported()) {
3151                 ALOGI("%s: camera %s does not support color output. skipping",
3152                         __FUNCTION__, cameraId);
3153                 ACameraMetadata_free(chars);
3154                 continue;
3155             }
3156             ACameraMetadata_free(chars);
3157         }
3158 
3159         ret = testCase.openCamera(cameraId);
3160         if (ret != ACAMERA_OK) {
3161             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3162             goto cleanup;
3163         }
3164 
3165         chars = testCase.getCameraChars(i);
3166         if (chars == nullptr) {
3167             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3168             goto cleanup;
3169         }
3170         StaticInfo staticInfo(chars);
3171 
3172         usleep(200000); // sleep to give some time for callbacks to happen
3173 
3174         if (testCase.isCameraAvailable(cameraId)) {
3175             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3176             goto cleanup;
3177         }
3178 
3179         ImageReaderListener readerListener;
3180         AImageReader_ImageListener readerCb { &readerListener, cb };
3181         readerListener.setDumpFilePathBase(outPath);
3182 
3183         int32_t testWidth, testHeight;
3184         switch (format) {
3185             case AIMAGE_FORMAT_JPEG:
3186                 testWidth = TEST_WIDTH;
3187                 testHeight = TEST_HEIGHT;
3188                 break;
3189             case AIMAGE_FORMAT_Y8:
3190             case AIMAGE_FORMAT_HEIC:
3191             case AIMAGE_FORMAT_DEPTH_JPEG:
3192                 if (!staticInfo.getMaxSizeForFormat(format, &testWidth, &testHeight)) {
3193                     // No corresponding format support, skip this device.
3194                     ACameraMetadata_free(chars);
3195                     chars = nullptr;
3196                     ret = testCase.closeCamera();
3197                     if (ret != ACAMERA_OK) {
3198                         LOG_ERROR(errorString, "Camera %s failed to close. ret %d ", cameraId, ret);
3199                         goto cleanup;
3200                     }
3201 
3202                     continue;
3203                 }
3204                 break;
3205             default:
3206                 LOG_ERROR(errorString, "Testcase doesn't yet support format %d", format);
3207                 goto cleanup;
3208         }
3209         mediaRet = testCase.initImageReaderWithErrorLog(
3210                 testWidth, testHeight, format, NUM_TEST_IMAGES,
3211                 &readerCb);
3212         if (mediaRet != AMEDIA_OK) {
3213             // Don't log error here. testcase did it
3214             goto cleanup;
3215         }
3216 
3217         ret = testCase.createCaptureSessionWithLog();
3218         if (ret != ACAMERA_OK) {
3219             // Don't log error here. testcase did it
3220             goto cleanup;
3221         }
3222 
3223         ret = testCase.createRequestsWithErrorLog();
3224         if (ret != ACAMERA_OK) {
3225             // Don't log error here. testcase did it
3226             goto cleanup;
3227         }
3228 
3229         CaptureResultListener resultListener;
3230         ACameraCaptureSession_captureCallbacks resultCb {
3231             &resultListener,
3232             CaptureResultListener::onCaptureStart,
3233             CaptureResultListener::onCaptureProgressed,
3234             CaptureResultListener::onCaptureCompleted,
3235             CaptureResultListener::onCaptureFailed,
3236             CaptureResultListener::onCaptureSequenceCompleted,
3237             CaptureResultListener::onCaptureSequenceAborted,
3238             CaptureResultListener::onCaptureBufferLost
3239         };
3240         resultListener.setRequestSave(true);
3241         ACaptureRequest* requestTemplate = nullptr;
3242         ret = testCase.getStillRequest(&requestTemplate);
3243         if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3244             // Don't log error here. testcase did it
3245             goto cleanup;
3246         }
3247 
3248         // Do some still capture
3249         int lastSeqId = -1;
3250         for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
3251             ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
3252             ACaptureRequest_setUserContext(req, (void*) capture);
3253             int seqId;
3254             ret = testCase.capture(req, &resultCb, &seqId);
3255             if (ret != ACAMERA_OK) {
3256                 LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
3257                         cameraId, capture, ret);
3258                 goto cleanup;
3259             }
3260             if (capture == NUM_TEST_IMAGES - 1) {
3261                 lastSeqId = seqId;
3262             }
3263             ACaptureRequest_free(req);
3264         }
3265 
3266         // wait until last sequence complete
3267         resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 5);
3268 
3269         std::vector<ACaptureRequest*> completedRequests;
3270         resultListener.getCompletedRequests(&completedRequests);
3271 
3272         if (completedRequests.size() != NUM_TEST_IMAGES) {
3273             LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
3274                     cameraId, NUM_TEST_IMAGES, completedRequests.size());
3275             goto cleanup;
3276         }
3277 
3278         for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
3279             intptr_t userContext = -1;
3280             ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
3281             if (ret != ACAMERA_OK) {
3282                 LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
3283                 goto cleanup;
3284             }
3285 
3286             if (userContext != i) {
3287                 LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
3288                         "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
3289                 goto cleanup;
3290             }
3291         }
3292 
3293         int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
3294                 format, testWidth, testHeight);
3295         if (minFrameDurationNs < 0) {
3296             LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
3297             goto cleanup;
3298         }
3299         int64_t stallDurationNs = (format == AIMAGE_FORMAT_Y8) ? 0 :
3300                 staticInfo.getStallDurationFor(format, testWidth, testHeight);
3301         if (stallDurationNs < 0) {
3302             LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
3303             goto cleanup;
3304         }
3305 
3306         int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
3307         constexpr int64_t waitPerIterationUs = 100000;
3308         constexpr int64_t usToNs = 1000;
3309         int totalWaitIteration = 50;
3310 
3311         // Allow 1.5x margin
3312         if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
3313             totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
3314         }
3315 
3316         // wait until all capture finished
3317         for (int i = 0; i < totalWaitIteration; i++) {
3318             usleep(waitPerIterationUs);
3319             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
3320                 ALOGI("Session take ~%d ms to capture %d images",
3321                         i*100, NUM_TEST_IMAGES);
3322                 break;
3323             }
3324         }
3325 
3326         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
3327             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
3328                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
3329             goto cleanup;
3330         }
3331 
3332         ret = testCase.resetWithErrorLog();
3333         if (ret != ACAMERA_OK) {
3334             // Don't log error here. testcase did it
3335             goto cleanup;
3336         }
3337 
3338         usleep(200000); // sleep to give some time for callbacks to happen
3339 
3340         if (!testCase.isCameraAvailable(cameraId)) {
3341             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3342             goto cleanup;
3343         }
3344     }
3345 
3346     ret = testCase.deInit();
3347     if (ret != ACAMERA_OK) {
3348         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3349         goto cleanup;
3350     }
3351 
3352     pass = true;
3353 
3354 cleanup:
3355     if (outPath != nullptr) {
3356         env->ReleaseStringUTFChars(jOutPath, outPath);
3357     }
3358 
3359     if (chars != nullptr) {
3360         ACameraMetadata_free(chars);
3361         chars = nullptr;
3362     }
3363 
3364     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3365     if (!pass) {
3366         throwAssertionError(env, errorString);
3367     }
3368     return pass;
3369 }
3370 
3371 // Test the camera NDK capture failure path by acquiring the maximum amount of ImageReader
3372 // buffers available. Since there is no circulation of camera images, the registered output
3373 // surface will eventually run out of free buffers and start reporting capture errors.
3374 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCaptureFailureNative(JNIEnv * env)3375 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
3376 testCameraDeviceCaptureFailureNative(JNIEnv* env) {
3377     const size_t NUM_TEST_IMAGES = 10;
3378     const size_t NUM_FAILED_FRAMES = 3; // Wait for at least 3 consecutive failed capture requests
3379     const int64_t NUM_TOTAL_FRAMES = 60; // Avoid waiting for more than 60 frames
3380     const size_t TEST_WIDTH  = 640;
3381     const size_t TEST_HEIGHT = 480;
3382     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3383     int numCameras = 0;
3384     bool pass = false;
3385     PreviewTestCase testCase;
3386     uint32_t timeoutSec = 10; // It is important to keep this timeout bigger than the framework
3387                               // timeout
3388 
3389     camera_status_t ret = testCase.initWithErrorLog();
3390     if (ret != ACAMERA_OK) {
3391         // Don't log error here. testcase did it
3392         goto exit;
3393     }
3394 
3395     numCameras = testCase.getNumCameras();
3396     if (numCameras < 0) {
3397         LOG_ERROR(errorString, "Testcase returned negative number of cameras: %d", numCameras);
3398         goto exit;
3399     }
3400 
3401     for (int i = 0; i < numCameras; i++) {
3402         const char* cameraId = testCase.getCameraId(i);
3403         if (cameraId == nullptr) {
3404             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3405             goto exit;
3406         }
3407 
3408         std::unique_ptr<ACameraMetadata> chars(testCase.getCameraChars(i));
3409         if (chars.get() == nullptr) {
3410             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3411             goto exit;
3412         }
3413         StaticInfo staticInfo(chars.get());
3414 
3415         if (!staticInfo.isColorOutputSupported()) {
3416             continue;
3417         }
3418 
3419         ret = testCase.openCamera(cameraId);
3420         if (ret != ACAMERA_OK) {
3421             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3422             goto exit;
3423         }
3424 
3425         if (testCase.isCameraAvailable(cameraId)) {
3426             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3427             goto exit;
3428         }
3429 
3430         ImageReaderListener readerListener;
3431         AImageReader_ImageListener readerCb =
3432                 { &readerListener, ImageReaderListener::acquireImageCb };
3433         mediaRet = testCase.initImageReaderWithErrorLog(TEST_WIDTH, TEST_HEIGHT,
3434                 AIMAGE_FORMAT_YUV_420_888, NUM_TEST_IMAGES, &readerCb);
3435         if (mediaRet != AMEDIA_OK) {
3436             // Don't log error here. testcase did it
3437             goto exit;
3438         }
3439 
3440         ret = testCase.createCaptureSessionWithLog();
3441         if (ret != ACAMERA_OK) {
3442             // Don't log error here. testcase did it
3443             goto exit;
3444         }
3445 
3446         ret = testCase.createRequestsWithErrorLog();
3447         if (ret != ACAMERA_OK) {
3448             // Don't log error here. testcase did it
3449             goto exit;
3450         }
3451 
3452         CaptureResultListener resultListener;
3453         ACameraCaptureSession_captureCallbacks resultCb {
3454             &resultListener,
3455             CaptureResultListener::onCaptureStart,
3456             CaptureResultListener::onCaptureProgressed,
3457             CaptureResultListener::onCaptureCompleted,
3458             CaptureResultListener::onCaptureFailed,
3459             CaptureResultListener::onCaptureSequenceCompleted,
3460             CaptureResultListener::onCaptureSequenceAborted,
3461             CaptureResultListener::onCaptureBufferLost
3462         };
3463         ACaptureRequest* requestTemplate = nullptr;
3464         ret = testCase.getStillRequest(&requestTemplate);
3465         if (ret != ACAMERA_OK || requestTemplate == nullptr) {
3466             // Don't log error here. testcase did it
3467             goto exit;
3468         }
3469 
3470         int seqId;
3471         ret = testCase.startRepeatingRequest(&seqId, requestTemplate, &resultCb);
3472         if (ret != ACAMERA_OK) {
3473             // Don't log error here. testcase did it
3474             goto exit;
3475         }
3476 
3477         size_t failedRequestCount;
3478         int64_t lastFrameNumber;
3479         int64_t lastFailedRequestNumber = -1;
3480         failedRequestCount = lastFrameNumber = 0;
3481         while ((failedRequestCount < NUM_FAILED_FRAMES) && (lastFrameNumber < NUM_TOTAL_FRAMES)) {
3482             auto frameArrived = resultListener.waitForFrameNumber(lastFrameNumber, timeoutSec);
3483             if (!frameArrived) {
3484                 LOG_ERROR(errorString, "Camera %s timed out waiting on last frame number!",
3485                         cameraId);
3486                 goto exit;
3487             }
3488             auto failedFrameNumber = resultListener.checkForFailure(lastFrameNumber) ?
3489                     lastFrameNumber : -1;
3490             if (lastFailedRequestNumber != failedFrameNumber) {
3491                 if ((lastFailedRequestNumber + 1) == failedFrameNumber) {
3492                     failedRequestCount++;
3493                 } else {
3494                     failedRequestCount = 1;
3495                 }
3496                 lastFailedRequestNumber = failedFrameNumber;
3497             }
3498             lastFrameNumber++;
3499         }
3500 
3501         ret = testCase.stopPreview();
3502         if (ret != ACAMERA_OK) {
3503             LOG_ERROR(errorString, "stopPreview failed!");
3504             goto exit;
3505         }
3506 
3507         ret = testCase.resetWithErrorLog();
3508         if (ret != ACAMERA_OK) {
3509             // Don't log error here. testcase did it
3510             goto exit;
3511         }
3512 
3513         usleep(100000); // sleep to give some time for callbacks to happen
3514 
3515         if (!testCase.isCameraAvailable(cameraId)) {
3516             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3517             goto exit;
3518         }
3519 
3520         if (failedRequestCount < NUM_FAILED_FRAMES) {
3521             LOG_ERROR(errorString, "Unable to receive %zu consecutive capture failures within"
3522                     " %" PRId64 " capture requests", NUM_FAILED_FRAMES, NUM_TOTAL_FRAMES);
3523             goto exit;
3524         }
3525     }
3526 
3527     ret = testCase.deInit();
3528     if (ret != ACAMERA_OK) {
3529         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3530         goto exit;
3531     }
3532 
3533     pass = true;
3534 
3535 exit:
3536 
3537     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3538     if (!pass) {
3539         throwAssertionError(env, errorString);
3540     }
3541 
3542     return pass;
3543 }
3544 
3545 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath)3546 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3547 testJpegNative(
3548         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
3549     ALOGV("%s", __FUNCTION__);
3550     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_JPEG,
3551             ImageReaderListener::validateImageCb);
3552 }
3553 
3554 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testY8Native(JNIEnv * env,jclass,jstring jOutPath)3555 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3556 testY8Native(
3557         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
3558     ALOGV("%s", __FUNCTION__);
3559     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_Y8,
3560             ImageReaderListener::validateImageCb);
3561 }
3562 
3563 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testHeicNative(JNIEnv * env,jclass,jstring jOutPath)3564 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3565 testHeicNative(
3566         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
3567     ALOGV("%s", __FUNCTION__);
3568     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_HEIC,
3569             ImageReaderListener::validateImageCb);
3570 }
3571 
3572 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testDepthJpegNative(JNIEnv * env,jclass,jstring jOutPath)3573 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3574 testDepthJpegNative(
3575         JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
3576     ALOGV("%s", __FUNCTION__);
3577     return nativeImageReaderTestBase(env, jOutPath, AIMAGE_FORMAT_DEPTH_JPEG,
3578             ImageReaderListener::validateImageCb);
3579 }
3580 
3581 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testImageReaderCloseAcquiredImagesNative(JNIEnv * env,jclass)3582 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
3583 testImageReaderCloseAcquiredImagesNative(
3584         JNIEnv* env, jclass /*clazz*/) {
3585     ALOGV("%s", __FUNCTION__);
3586     return nativeImageReaderTestBase(env, nullptr, AIMAGE_FORMAT_JPEG,
3587             ImageReaderListener::acquireImageCb);
3588 }
3589 
3590 template <>
3591 struct std::default_delete<ACameraManager> {
operator ()std::default_delete3592     inline void operator()(ACameraManager* manager) const { ACameraManager_delete(manager); }
3593 };
3594 
3595 class AvailabilityContext {
3596     public:
3597         AvailabilityContext();
3598         ~AvailabilityContext();
3599 
3600         camera_status_t initialize();
3601         int getAcessCallbackCountAndReset();
3602 
3603     private:
3604         std::unique_ptr<ACameraManager> mCameraManager;
3605         std::unique_ptr<CameraServiceListener> mServiceListener;
3606         std::unique_ptr<ACameraManager_ExtendedAvailabilityCallbacks> mServiceCb;
3607 };
3608 
AvailabilityContext()3609 AvailabilityContext::AvailabilityContext() :
3610     mCameraManager(ACameraManager_create()),
3611     mServiceListener(std::make_unique<CameraServiceListener>()),
3612     mServiceCb(std::make_unique<ACameraManager_ExtendedAvailabilityCallbacks>()) {
3613         mServiceCb->availabilityCallbacks.context = mServiceListener.get();
3614         mServiceCb->availabilityCallbacks.onCameraAvailable = CameraServiceListener::onAvailable;
3615         mServiceCb->availabilityCallbacks.onCameraUnavailable =
3616                 CameraServiceListener::onUnavailable;
3617         mServiceCb->onCameraAccessPrioritiesChanged =
3618                 CameraServiceListener::onCameraAccessPrioritiesChanged;
3619 }
3620 
initialize()3621 camera_status_t AvailabilityContext::initialize() {
3622     auto rc = ACameraManager_registerExtendedAvailabilityCallback(mCameraManager.get(),
3623             mServiceCb.get());
3624     if (rc != ACAMERA_OK) {
3625         LOG_ERROR(errorString, "Register availability callback failed: rc %d", rc);
3626         return rc;
3627     }
3628 
3629     ACameraIdList* cameraIdList = nullptr;
3630     rc = ACameraManager_getCameraIdList(mCameraManager.get(), &cameraIdList);
3631     if (rc != ACAMERA_OK) {
3632         LOG_ERROR(errorString, "Get camera id list failed: ret %d", rc);
3633         return rc;
3634     }
3635     ACameraManager_deleteCameraIdList(cameraIdList);
3636 
3637     return rc;
3638 }
3639 
getAcessCallbackCountAndReset()3640 int AvailabilityContext::getAcessCallbackCountAndReset() {
3641     auto ret = mServiceListener->getCameraAccessPrioritiesChangedCount();
3642     mServiceListener->resetCount();
3643     return ret;
3644 }
3645 
~AvailabilityContext()3646 AvailabilityContext::~AvailabilityContext() {
3647     if (mServiceCb != nullptr) {
3648         camera_status_t ret = ACameraManager_unregisterExtendedAvailabilityCallback(
3649                 mCameraManager.get(), mServiceCb.get());
3650         if (ret != ACAMERA_OK) {
3651             ALOGE("Unregister availability callback failed: ret %d", ret);
3652         }
3653     }
3654 }
3655 
3656 extern "C" jlong
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_initializeAvailabilityCallbacksNative(JNIEnv * env,jclass)3657 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3658 initializeAvailabilityCallbacksNative(
3659         JNIEnv* env, jclass /*clazz*/) {
3660     ALOGV("%s", __FUNCTION__);
3661 
3662     AvailabilityContext *ctx = new AvailabilityContext();
3663 
3664     auto rc = ctx->initialize();
3665     if (rc != ACAMERA_OK) {
3666         LOG_ERROR(errorString, "Availability context initialization failed: %d", rc);
3667         return 0;
3668     }
3669 
3670     return (jlong) ctx;
3671 }
3672 
3673 extern "C" jint
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_getAccessCallbacksCountAndResetNative(JNIEnv * env,jclass,jlong context)3674 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3675 getAccessCallbacksCountAndResetNative(
3676         JNIEnv* env, jclass /*clazz*/, jlong context) {
3677     ALOGV("%s", __FUNCTION__);
3678 
3679     if (context == 0) {
3680         LOG_ERROR(errorString, "Invalid availability context");
3681         return 0;
3682     }
3683 
3684     AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
3685     return ctx->getAcessCallbackCountAndReset();
3686 }
3687 
3688 extern "C" void
Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_releaseAvailabilityCallbacksNative(JNIEnv * env,jclass,jlong context)3689 Java_android_hardware_multiprocess_camera_cts_CameraEvictionTest_\
3690 releaseAvailabilityCallbacksNative(
3691         JNIEnv* env, jclass /*clazz*/, jlong context) {
3692     ALOGV("%s", __FUNCTION__);
3693 
3694     if (context == 0) {
3695         return;
3696     }
3697 
3698     AvailabilityContext* ctx = reinterpret_cast<AvailabilityContext*>(context);
3699     delete ctx;
3700 }
3701 
3702 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface)3703 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
3704 testStillCaptureNative(
3705         JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
3706     ALOGV("%s", __FUNCTION__);
3707     const int NUM_TEST_IMAGES = 10;
3708     const int TEST_WIDTH  = 640;
3709     const int TEST_HEIGHT = 480;
3710     media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
3711     int numCameras = 0;
3712     bool pass = false;
3713     PreviewTestCase testCase;
3714     ACameraMetadata* chars = nullptr;
3715 
3716     const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
3717     ALOGI("%s: out path is %s", __FUNCTION__, outPath);
3718 
3719     camera_status_t ret = testCase.initWithErrorLog();
3720     if (ret != ACAMERA_OK) {
3721         // Don't log error here. testcase did it
3722         goto cleanup;
3723     }
3724 
3725     numCameras = testCase.getNumCameras();
3726     if (numCameras < 0) {
3727         LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
3728         goto cleanup;
3729     }
3730 
3731     for (int i = 0; i < numCameras; i++) {
3732         const char* cameraId = testCase.getCameraId(i);
3733         if (cameraId == nullptr) {
3734             LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
3735             goto cleanup;
3736         }
3737 
3738         {
3739             ACameraMetadata* chars = testCase.getCameraChars(cameraId);
3740             StaticInfo staticInfo(chars);
3741             if (!staticInfo.isColorOutputSupported()) {
3742                 ALOGI("%s: camera %s does not support color output. skipping",
3743                         __FUNCTION__, cameraId);
3744                 ACameraMetadata_free(chars);
3745                 continue;
3746             }
3747             ACameraMetadata_free(chars);
3748         }
3749 
3750         ret = testCase.openCamera(cameraId);
3751         if (ret != ACAMERA_OK) {
3752             LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
3753             goto cleanup;
3754         }
3755 
3756         chars = testCase.getCameraChars(i);
3757         if (chars == nullptr) {
3758             LOG_ERROR(errorString, "Get camera %s characteristics failure", cameraId);
3759             goto cleanup;
3760         }
3761         StaticInfo staticInfo(chars);
3762 
3763         usleep(100000); // sleep to give some time for callbacks to happen
3764 
3765         if (testCase.isCameraAvailable(cameraId)) {
3766             LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
3767             goto cleanup;
3768         }
3769 
3770         ImageReaderListener readerListener;
3771         AImageReader_ImageListener readerCb {
3772             &readerListener,
3773             ImageReaderListener::validateImageCb
3774         };
3775         readerListener.setDumpFilePathBase(outPath);
3776         mediaRet = testCase.initImageReaderWithErrorLog(
3777                 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES,
3778                 &readerCb);
3779         if (mediaRet != AMEDIA_OK) {
3780             // Don't log error here. testcase did it
3781             goto cleanup;
3782         }
3783 
3784         ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
3785         if (previewAnw == nullptr) {
3786             LOG_ERROR(errorString, "Null ANW from preview surface!");
3787             goto cleanup;
3788         }
3789 
3790         ret = testCase.createCaptureSessionWithLog();
3791         if (ret != ACAMERA_OK) {
3792             // Don't log error here. testcase did it
3793             goto cleanup;
3794         }
3795 
3796         ret = testCase.createRequestsWithErrorLog();
3797         if (ret != ACAMERA_OK) {
3798             // Don't log error here. testcase did it
3799             goto cleanup;
3800         }
3801 
3802         ret = testCase.startPreview();
3803         if (ret != ACAMERA_OK) {
3804             LOG_ERROR(errorString, "Start preview failed!");
3805             goto cleanup;
3806         }
3807 
3808         // Let preview run some time
3809         sleep(3);
3810 
3811         // Do some still capture
3812         for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
3813             ret = testCase.takePicture();
3814             if (ret != ACAMERA_OK) {
3815                 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
3816                         cameraId, capture, ret);
3817                 goto cleanup;
3818             }
3819         }
3820 
3821         int64_t minFrameDurationNs = staticInfo.getMinFrameDurationFor(
3822                 AIMAGE_FORMAT_JPEG, TEST_WIDTH, TEST_HEIGHT);
3823         if (minFrameDurationNs < 0) {
3824             LOG_ERROR(errorString, "Get camera %s minFrameDuration failed", cameraId);
3825             goto cleanup;
3826         }
3827         int64_t stallDurationNs = staticInfo.getStallDurationFor(
3828                 AIMAGE_FORMAT_JPEG, TEST_WIDTH, TEST_HEIGHT);
3829         if (stallDurationNs < 0) {
3830             LOG_ERROR(errorString, "Get camera %s stallDuration failed", cameraId);
3831             goto cleanup;
3832         }
3833 
3834         int64_t expectedDurationNs = (minFrameDurationNs + stallDurationNs) * NUM_TEST_IMAGES;
3835         constexpr int64_t waitPerIterationUs = 100000;
3836         constexpr int64_t usToNs = 1000;
3837         int totalWaitIteration = 50;
3838 
3839         // Allow 1.5x margin
3840         if (expectedDurationNs * 3 / 2 > totalWaitIteration * waitPerIterationUs * usToNs) {
3841             totalWaitIteration = expectedDurationNs * 3 / 2 / waitPerIterationUs / usToNs;
3842         }
3843 
3844         // wait until all capture finished
3845         for (int i = 0; i < totalWaitIteration; i++) {
3846             usleep(waitPerIterationUs);
3847             if (readerListener.onImageAvailableCount() == NUM_TEST_IMAGES) {
3848                 ALOGI("Session take ~%d ms to capture %d images",
3849                         i*100, NUM_TEST_IMAGES);
3850                 break;
3851             }
3852         }
3853 
3854         if (readerListener.onImageAvailableCount() != NUM_TEST_IMAGES) {
3855             LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
3856                     cameraId, NUM_TEST_IMAGES, readerListener.onImageAvailableCount());
3857             goto cleanup;
3858         }
3859 
3860         ret = testCase.resetWithErrorLog();
3861         if (ret != ACAMERA_OK) {
3862             // Don't log error here. testcase did it
3863             goto cleanup;
3864         }
3865 
3866         usleep(100000); // sleep to give some time for callbacks to happen
3867 
3868         if (!testCase.isCameraAvailable(cameraId)) {
3869             LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
3870             goto cleanup;
3871         }
3872     }
3873 
3874     ret = testCase.deInit();
3875     if (ret != ACAMERA_OK) {
3876         LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
3877         goto cleanup;
3878     }
3879 
3880     pass = true;
3881 cleanup:
3882     env->ReleaseStringUTFChars(jOutPath, outPath);
3883 
3884     if (chars != nullptr) {
3885         ACameraMetadata_free(chars);
3886         chars = nullptr;
3887     }
3888 
3889     ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
3890     if (!pass) {
3891         throwAssertionError(env, errorString);
3892     }
3893     return pass;
3894 }
3895 
3896