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