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