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