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