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