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