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 <string>
22 #include <map>
23 #include <mutex>
24 #include <unistd.h>
25 #include <assert.h>
26 #include <jni.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include <android/native_window_jni.h>
31
32 #include "NdkCameraError.h"
33 #include "NdkCameraManager.h"
34 #include "NdkCameraDevice.h"
35 #include "NdkCameraCaptureSession.h"
36 #include "NdkImage.h"
37 #include "NdkImageReader.h"
38
39 #define LOG_ERROR(buf, ...) sprintf(buf, __VA_ARGS__); \
40 ALOGE("%s", buf);
41
42 namespace {
43 const int MAX_ERROR_STRING_LEN = 512;
44 char errorString[MAX_ERROR_STRING_LEN];
45 }
46
47 class CameraServiceListener {
48 public:
onAvailable(void * obj,const char * cameraId)49 static void onAvailable(void* obj, const char* cameraId) {
50 ALOGV("Camera %s onAvailable", cameraId);
51 if (obj == nullptr) {
52 return;
53 }
54 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
55 std::lock_guard<std::mutex> lock(thiz->mMutex);
56 thiz->mOnAvailableCount++;
57 thiz->mAvailableMap[cameraId] = true;
58 return;
59 }
60
onUnavailable(void * obj,const char * cameraId)61 static void onUnavailable(void* obj, const char* cameraId) {
62 ALOGV("Camera %s onUnavailable", cameraId);
63 if (obj == nullptr) {
64 return;
65 }
66 CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
67 std::lock_guard<std::mutex> lock(thiz->mMutex);
68 thiz->mOnUnavailableCount++;
69 thiz->mAvailableMap[cameraId] = false;
70 return;
71 }
72
resetCount()73 void resetCount() {
74 std::lock_guard<std::mutex> lock(mMutex);
75 mOnAvailableCount = 0;
76 mOnUnavailableCount = 0;
77 return;
78 }
79
getAvailableCount()80 int getAvailableCount() {
81 std::lock_guard<std::mutex> lock(mMutex);
82 return mOnAvailableCount;
83 }
84
getUnavailableCount()85 int getUnavailableCount() {
86 std::lock_guard<std::mutex> lock(mMutex);
87 return mOnUnavailableCount;
88 }
89
isAvailable(const char * cameraId)90 bool isAvailable(const char* cameraId) {
91 std::lock_guard<std::mutex> lock(mMutex);
92 if (mAvailableMap.count(cameraId) == 0) {
93 return false;
94 }
95 return mAvailableMap[cameraId];
96 }
97
98 private:
99 std::mutex mMutex;
100 int mOnAvailableCount = 0;
101 int mOnUnavailableCount = 0;
102 std::map<std::string, bool> mAvailableMap;
103 };
104
105 class CameraDeviceListener {
106 public:
onDisconnected(void * obj,ACameraDevice * device)107 static void onDisconnected(void* obj, ACameraDevice* device) {
108 ALOGV("Camera %s is disconnected!", ACameraDevice_getId(device));
109 if (obj == nullptr) {
110 return;
111 }
112 CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
113 std::lock_guard<std::mutex> lock(thiz->mMutex);
114 thiz->mOnDisconnect++;
115 return;
116 }
117
onError(void * obj,ACameraDevice * device,int errorCode)118 static void onError(void* obj, ACameraDevice* device, int errorCode) {
119 ALOGV("Camera %s receive error %d!", ACameraDevice_getId(device), errorCode);
120 if (obj == nullptr) {
121 return;
122 }
123 CameraDeviceListener* thiz = reinterpret_cast<CameraDeviceListener*>(obj);
124 std::lock_guard<std::mutex> lock(thiz->mMutex);
125 thiz->mOnError++;
126 thiz->mLatestError = errorCode;
127 return;
128 }
129
130 private:
131 std::mutex mMutex;
132 int mOnDisconnect = 0;
133 int mOnError = 0;
134 int mLatestError = 0;
135 };
136
137 class CaptureSessionListener {
138
139 public:
onClosed(void * obj,ACameraCaptureSession * session)140 static void onClosed(void* obj, ACameraCaptureSession *session) {
141 // TODO: might want an API to query cameraId even session is closed?
142 ALOGV("Session %p is closed!", session);
143 if (obj == nullptr) {
144 return;
145 }
146 CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
147 std::lock_guard<std::mutex> lock(thiz->mMutex);
148 thiz->mIsClosed = true;
149 thiz->mOnClosed++; // Should never > 1
150 }
151
onReady(void * obj,ACameraCaptureSession * session)152 static void onReady(void* obj, ACameraCaptureSession *session) {
153 ALOGV("%s", __FUNCTION__);
154 if (obj == nullptr) {
155 return;
156 }
157 CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
158 std::lock_guard<std::mutex> lock(thiz->mMutex);
159 ACameraDevice* device = nullptr;
160 camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
161 // There will be one onReady fired after session closed
162 if (ret != ACAMERA_OK && !thiz->mIsClosed) {
163 ALOGE("%s Getting camera device from session callback failed!",
164 __FUNCTION__);
165 thiz->mInError = true;
166 }
167 ALOGV("Session for camera %s is ready!", ACameraDevice_getId(device));
168 thiz->mIsIdle = true;
169 thiz->mOnReady++;
170 }
171
onActive(void * obj,ACameraCaptureSession * session)172 static void onActive(void* obj, ACameraCaptureSession *session) {
173 ALOGV("%s", __FUNCTION__);
174 if (obj == nullptr) {
175 return;
176 }
177 CaptureSessionListener* thiz = reinterpret_cast<CaptureSessionListener*>(obj);
178 std::lock_guard<std::mutex> lock(thiz->mMutex);
179 ACameraDevice* device = nullptr;
180 camera_status_t ret = ACameraCaptureSession_getDevice(session, &device);
181 if (ret != ACAMERA_OK) {
182 ALOGE("%s Getting camera device from session callback failed!",
183 __FUNCTION__);
184 thiz->mInError = true;
185 }
186 ALOGV("Session for camera %s is busy!", ACameraDevice_getId(device));
187 thiz->mIsIdle = false;
188 thiz->mOnActive;
189 }
190
isClosed()191 bool isClosed() {
192 std::lock_guard<std::mutex> lock(mMutex);
193 return mIsClosed;
194 }
195
isIdle()196 bool isIdle() {
197 std::lock_guard<std::mutex> lock(mMutex);
198 return mIsIdle;
199 }
200
isInError()201 bool isInError() {
202 std::lock_guard<std::mutex> lock(mMutex);
203 return mInError;
204 }
205
onClosedCount()206 int onClosedCount() {
207 std::lock_guard<std::mutex> lock(mMutex);
208 return mOnClosed;
209 }
210
onReadyCount()211 int onReadyCount() {
212 std::lock_guard<std::mutex> lock(mMutex);
213 return mOnReady;
214 }
215
onActiveCount()216 int onActiveCount() {
217 std::lock_guard<std::mutex> lock(mMutex);
218 return mOnActive;
219 }
220
reset()221 void reset() {
222 std::lock_guard<std::mutex> lock(mMutex);
223 mIsClosed = false;
224 mIsIdle = true;
225 mInError = false;
226 mOnClosed = 0;
227 mOnReady = 0;
228 mOnActive = 0;
229 }
230
231 private:
232 std::mutex mMutex;
233 bool mIsClosed = false;
234 bool mIsIdle = true;
235 bool mInError = false; // should always stay false
236 int mOnClosed = 0;
237 int mOnReady = 0;
238 int mOnActive = 0;
239 };
240
241 class ImageReaderListener {
242 public:
onImageAvailable(void * obj,AImageReader * reader)243 static void onImageAvailable(void* obj, AImageReader* reader) {
244 ALOGV("%s", __FUNCTION__);
245 if (obj == nullptr) {
246 return;
247 }
248 ImageReaderListener* thiz = reinterpret_cast<ImageReaderListener*>(obj);
249 std::lock_guard<std::mutex> lock(thiz->mMutex);
250 thiz->mOnImageAvailableCount++;
251
252 AImage* img = nullptr;
253 media_status_t ret = AImageReader_acquireNextImage(reader, &img);
254 if (ret != AMEDIA_OK || img == nullptr) {
255 ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
256 __FUNCTION__, reader, ret, img);
257 return;
258 }
259
260 // TODO: validate image content
261 int32_t format = -1;
262 ret = AImage_getFormat(img, &format);
263 if (ret != AMEDIA_OK || format == -1) {
264 ALOGE("%s: get format for image %p failed! ret: %d, format %d",
265 __FUNCTION__, img, ret, format);
266 }
267
268 // Save jpeg to SD card
269 if (thiz->mDumpFilePathBase && format == AIMAGE_FORMAT_JPEG) {
270 int32_t numPlanes = 0;
271 ret = AImage_getNumberOfPlanes(img, &numPlanes);
272 if (ret != AMEDIA_OK || numPlanes != 1) {
273 ALOGE("%s: get numPlanes for image %p failed! ret: %d, numPlanes %d",
274 __FUNCTION__, img, ret, numPlanes);
275 AImage_delete(img);
276 return;
277 }
278
279 int32_t width = -1, height = -1;
280 ret = AImage_getWidth(img, &width);
281 if (ret != AMEDIA_OK || width <= 0) {
282 ALOGE("%s: get width for image %p failed! ret: %d, width %d",
283 __FUNCTION__, img, ret, width);
284 AImage_delete(img);
285 return;
286 }
287
288 ret = AImage_getHeight(img, &height);
289 if (ret != AMEDIA_OK || height <= 0) {
290 ALOGE("%s: get height for image %p failed! ret: %d, height %d",
291 __FUNCTION__, img, ret, height);
292 AImage_delete(img);
293 return;
294 }
295
296 uint8_t* data = nullptr;
297 int dataLength = 0;
298 ret = AImage_getPlaneData(img, /*planeIdx*/0, &data, &dataLength);
299 if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
300 ALOGE("%s: get jpeg data for image %p failed! ret: %d, data %p, len %d",
301 __FUNCTION__, img, ret, data, dataLength);
302 AImage_delete(img);
303 return;
304 }
305
306 #if 0
307 char dumpFilePath[512];
308 sprintf(dumpFilePath, "%s/%dx%d.jpg", thiz->mDumpFilePathBase, width, height);
309 ALOGI("Writing jpeg file to %s", dumpFilePath);
310 FILE* file = fopen(dumpFilePath,"w+");
311
312 if (file != nullptr) {
313 fwrite(data, 1, dataLength, file);
314 fflush(file);
315 fclose(file);
316 }
317 #endif
318 }
319
320 AImage_delete(img);
321 }
322
onImageAvailableCount()323 int onImageAvailableCount() {
324 std::lock_guard<std::mutex> lock(mMutex);
325 return mOnImageAvailableCount;
326 }
327
setDumpFilePathBase(const char * path)328 void setDumpFilePathBase(const char* path) {
329 std::lock_guard<std::mutex> lock(mMutex);
330 mDumpFilePathBase = path;
331 }
332
reset()333 void reset() {
334 std::lock_guard<std::mutex> lock(mMutex);
335 mOnImageAvailableCount = 0;
336 mDumpFilePathBase = nullptr;
337 }
338
339 private:
340 // TODO: add mReader to make sure each listener is associated to one reader?
341 std::mutex mMutex;
342 int mOnImageAvailableCount = 0;
343 const char* mDumpFilePathBase = nullptr;
344 };
345
346 class StaticInfo {
347 public:
StaticInfo(ACameraMetadata * chars)348 explicit StaticInfo(ACameraMetadata* chars) : mChars(chars) {}
349
isColorOutputSupported()350 bool isColorOutputSupported() {
351 return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
352 }
353
isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap)354 bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
355 ACameraMetadata_const_entry entry;
356 ACameraMetadata_getConstEntry(mChars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
357 for (uint32_t i = 0; i < entry.count; i++) {
358 if (entry.data.u8[i] == cap) {
359 return true;
360 }
361 }
362 return false;
363 }
364 private:
365 const ACameraMetadata* mChars;
366 };
367
368 class PreviewTestCase {
369 public:
~PreviewTestCase()370 ~PreviewTestCase() {
371 resetCamera();
372 deInit();
373 if (mCameraManager) {
374 ACameraManager_delete(mCameraManager);
375 mCameraManager = nullptr;
376 }
377 }
378
PreviewTestCase()379 PreviewTestCase() {
380 // create is guaranteed to succeed;
381 createManager();
382 }
383
384 // Free all resources except camera manager
resetCamera()385 void resetCamera() {
386 mReaderListener.reset();
387 mSessionListener.reset();
388 if (mSession) {
389 ACameraCaptureSession_close(mSession);
390 mSession = nullptr;
391 }
392 if (mDevice) {
393 ACameraDevice_close(mDevice);
394 mDevice = nullptr;
395 }
396 if (mImgReader) {
397 AImageReader_delete(mImgReader);
398 // No need to call ANativeWindow_release on imageReaderAnw
399 mImgReaderAnw = nullptr;
400 mImgReader = nullptr;
401 }
402 if (mPreviewAnw) {
403 ANativeWindow_release(mPreviewAnw);
404 mPreviewAnw = nullptr;
405 }
406 if (mOutputs) {
407 ACaptureSessionOutputContainer_free(mOutputs);
408 mOutputs = nullptr;
409 }
410 if (mPreviewOutput) {
411 ACaptureSessionOutput_free(mPreviewOutput);
412 mPreviewOutput = nullptr;
413 }
414 if (mImgReaderOutput) {
415 ACaptureSessionOutput_free(mImgReaderOutput);
416 mImgReaderOutput = nullptr;
417 }
418 if (mPreviewRequest) {
419 ACaptureRequest_free(mPreviewRequest);
420 mPreviewRequest = nullptr;
421 }
422 if (mStillRequest) {
423 ACaptureRequest_free(mStillRequest);
424 mStillRequest = nullptr;
425 }
426 if (mReqPreviewOutput) {
427 ACameraOutputTarget_free(mReqPreviewOutput);
428 mReqPreviewOutput = nullptr;
429 }
430 if (mReqImgReaderOutput) {
431 ACameraOutputTarget_free(mReqImgReaderOutput);
432 mReqImgReaderOutput = nullptr;
433 }
434
435 mImgReaderInited = false;
436 mPreviewInited = false;
437 }
438
initWithErrorLog()439 camera_status_t initWithErrorLog() {
440 camera_status_t ret = ACameraManager_getCameraIdList(
441 mCameraManager, &mCameraIdList);
442 if (ret != ACAMERA_OK) {
443 LOG_ERROR(errorString, "Get camera id list failed: ret %d", ret);
444 return ret;
445 }
446 ret = ACameraManager_registerAvailabilityCallback(mCameraManager, &mServiceCb);
447 if (ret != ACAMERA_OK) {
448 LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
449 return ret;
450 }
451 mMgrInited = true;
452 return ACAMERA_OK;
453 }
454
deInit()455 camera_status_t deInit () {
456 if (!mMgrInited) {
457 return ACAMERA_OK;
458 }
459
460 camera_status_t ret = ACameraManager_unregisterAvailabilityCallback(
461 mCameraManager, &mServiceCb);
462 if (ret != ACAMERA_OK) {
463 ALOGE("Unregister availability callback failed: ret %d", ret);
464 return ret;
465 }
466
467 if (mCameraIdList) {
468 ACameraManager_deleteCameraIdList(mCameraIdList);
469 mCameraIdList = nullptr;
470 }
471 mMgrInited = false;
472 return ACAMERA_OK;
473 }
474
getNumCameras()475 int getNumCameras() {
476 if (!mMgrInited || !mCameraIdList) {
477 return -1;
478 }
479 return mCameraIdList->numCameras;
480 }
481
getCameraId(int idx)482 const char* getCameraId(int idx) {
483 if (!mMgrInited || !mCameraIdList || idx < 0 || idx >= mCameraIdList->numCameras) {
484 return nullptr;
485 }
486 return mCameraIdList->cameraIds[idx];
487 }
488
openCamera(const char * cameraId)489 camera_status_t openCamera(const char* cameraId) {
490 if (mDevice) {
491 ALOGE("Cannot open camera before closing previously open one");
492 return ACAMERA_ERROR_INVALID_PARAMETER;
493 }
494 mCameraId = cameraId;
495 return ACameraManager_openCamera(mCameraManager, cameraId, &mDeviceCb, &mDevice);
496 }
497
closeCamera()498 camera_status_t closeCamera() {
499 camera_status_t ret = ACameraDevice_close(mDevice);
500 mDevice = nullptr;
501 return ret;
502 }
503
isCameraAvailable(const char * cameraId)504 bool isCameraAvailable(const char* cameraId) {
505 if (!mMgrInited) {
506 ALOGE("Camera service listener has not been registered!");
507 }
508 return mServiceListener.isAvailable(cameraId);
509 }
510
initImageReaderWithErrorLog(int32_t width,int32_t height,int32_t format,int32_t maxImages)511 media_status_t initImageReaderWithErrorLog(
512 int32_t width, int32_t height, int32_t format, int32_t maxImages) {
513 if (mImgReader || mImgReaderAnw) {
514 LOG_ERROR(errorString, "Cannot init image reader before closing existing one");
515 return AMEDIA_ERROR_UNKNOWN;
516 }
517
518 media_status_t ret = AImageReader_new(
519 width, height, format,
520 maxImages, &mImgReader);
521 if (ret != AMEDIA_OK) {
522 LOG_ERROR(errorString, "Create image reader. ret %d", ret);
523 return ret;
524 }
525 if (mImgReader == nullptr) {
526 LOG_ERROR(errorString, "null image reader created");
527 return AMEDIA_ERROR_UNKNOWN;
528 }
529
530 ret = AImageReader_setImageListener(
531 mImgReader, &mReaderCb);
532 if (ret != AMEDIA_OK) {
533 LOG_ERROR(errorString, "Set AImageReader listener failed. ret %d", ret);
534 return ret;
535 }
536
537 ret = AImageReader_getWindow(mImgReader, &mImgReaderAnw);
538 if (ret != AMEDIA_OK) {
539 LOG_ERROR(errorString, "AImageReader_getWindow failed. ret %d", ret);
540 return ret;
541 }
542 if (mImgReaderAnw == nullptr) {
543 LOG_ERROR(errorString, "Null ANW from AImageReader!");
544 return AMEDIA_ERROR_UNKNOWN;
545 }
546 mImgReaderInited = true;
547 return AMEDIA_OK;
548 }
549
initPreviewAnw(JNIEnv * env,jobject jSurface)550 ANativeWindow* initPreviewAnw(JNIEnv* env, jobject jSurface) {
551 if (mPreviewAnw) {
552 ALOGE("Cannot init preview twice!");
553 return nullptr;
554 }
555 mPreviewAnw = ANativeWindow_fromSurface(env, jSurface);
556 mPreviewInited = true;
557 return mPreviewAnw;
558 }
559
createCaptureSessionWithLog()560 camera_status_t createCaptureSessionWithLog() {
561 if (mSession) {
562 LOG_ERROR(errorString, "Cannot create session before closing existing one");
563 return ACAMERA_ERROR_UNKNOWN;
564 }
565
566 if (!mMgrInited || (!mImgReaderInited && !mPreviewInited)) {
567 LOG_ERROR(errorString, "Cannot create session. mgrInit %d readerInit %d previewInit %d",
568 mMgrInited, mImgReaderInited, mPreviewInited);
569 return ACAMERA_ERROR_UNKNOWN;
570 }
571
572 camera_status_t ret = ACaptureSessionOutputContainer_create(&mOutputs);
573 if (ret != ACAMERA_OK) {
574 LOG_ERROR(errorString, "Create capture session output container failed. ret %d", ret);
575 return ret;
576 }
577
578 if (mImgReaderInited) {
579 ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
580 if (ret != ACAMERA_OK || mImgReaderOutput == nullptr) {
581 LOG_ERROR(errorString,
582 "Sesssion image reader output create fail! ret %d output %p",
583 ret, mImgReaderOutput);
584 if (ret == ACAMERA_OK) {
585 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
586 }
587 return ret;
588 }
589
590 ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
591 if (ret != ACAMERA_OK) {
592 LOG_ERROR(errorString, "Sesssion image reader output add failed! ret %d", ret);
593 return ret;
594 }
595 }
596
597 if (mPreviewInited) {
598 ret = ACaptureSessionOutput_create(mPreviewAnw, &mPreviewOutput);
599 if (ret != ACAMERA_OK || mPreviewOutput == nullptr) {
600 LOG_ERROR(errorString,
601 "Sesssion preview output create fail! ret %d output %p",
602 ret, mPreviewOutput);
603 if (ret == ACAMERA_OK) {
604 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but output is null
605 }
606 return ret;
607 }
608
609 ret = ACaptureSessionOutputContainer_add(mOutputs, mPreviewOutput);
610 if (ret != ACAMERA_OK) {
611 LOG_ERROR(errorString, "Sesssion preview output add failed! ret %d", ret);
612 return ret;
613 }
614 }
615
616 ret = ACameraDevice_createCaptureSession(
617 mDevice, mOutputs, &mSessionCb, &mSession);
618 if (ret != ACAMERA_OK || mSession == nullptr) {
619 LOG_ERROR(errorString, "Create session for camera %s failed. ret %d session %p",
620 mCameraId, ret, mSession);
621 if (ret == ACAMERA_OK) {
622 ret = ACAMERA_ERROR_UNKNOWN; // ret OK but session is null
623 }
624 return ret;
625 }
626
627 return ACAMERA_OK;
628 }
629
closeSession()630 void closeSession() {
631 if (mSession != nullptr) {
632 ACameraCaptureSession_close(mSession);
633 }
634 if (mOutputs) {
635 ACaptureSessionOutputContainer_free(mOutputs);
636 mOutputs = nullptr;
637 }
638 if (mPreviewOutput) {
639 ACaptureSessionOutput_free(mPreviewOutput);
640 mPreviewOutput = nullptr;
641 }
642 if (mImgReaderOutput) {
643 ACaptureSessionOutput_free(mImgReaderOutput);
644 mImgReaderOutput = nullptr;
645 }
646 mSession = nullptr;
647 }
648
createRequestsWithErrorLog()649 camera_status_t createRequestsWithErrorLog() {
650 if (mPreviewRequest || mStillRequest) {
651 LOG_ERROR(errorString, "Cannot create requests before deleteing existing one");
652 return ACAMERA_ERROR_UNKNOWN;
653 }
654
655 if (mDevice == nullptr || (!mPreviewInited && !mImgReaderInited)) {
656 LOG_ERROR(errorString,
657 "Cannot create request. device %p previewInit %d readeInit %d",
658 mDevice, mPreviewInited, mImgReaderInited);
659 return ACAMERA_ERROR_UNKNOWN;
660 }
661
662 camera_status_t ret;
663 if (mPreviewInited) {
664 ret = ACameraDevice_createCaptureRequest(
665 mDevice, TEMPLATE_PREVIEW, &mPreviewRequest);
666 if (ret != ACAMERA_OK) {
667 LOG_ERROR(errorString, "Camera %s create preview request failed. ret %d",
668 mCameraId, ret);
669 return ret;
670 }
671
672 ret = ACameraOutputTarget_create(mPreviewAnw, &mReqPreviewOutput);
673 if (ret != ACAMERA_OK) {
674 LOG_ERROR(errorString,
675 "Camera %s create request preview output target failed. ret %d",
676 mCameraId, ret);
677 return ret;
678 }
679
680 ret = ACaptureRequest_addTarget(mPreviewRequest, mReqPreviewOutput);
681 if (ret != ACAMERA_OK) {
682 LOG_ERROR(errorString, "Camera %s add preview request output failed. ret %d",
683 mCameraId, ret);
684 return ret;
685 }
686 } else {
687 ALOGI("Preview not inited. Will not create preview request!");
688 }
689
690 if (mImgReaderInited) {
691 ret = ACameraDevice_createCaptureRequest(
692 mDevice, TEMPLATE_STILL_CAPTURE, &mStillRequest);
693 if (ret != ACAMERA_OK) {
694 LOG_ERROR(errorString, "Camera %s create still request failed. ret %d",
695 mCameraId, ret);
696 return ret;
697 }
698
699 ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
700 if (ret != ACAMERA_OK) {
701 LOG_ERROR(errorString,
702 "Camera %s create request reader output target failed. ret %d",
703 mCameraId, ret);
704 return ret;
705 }
706
707 ret = ACaptureRequest_addTarget(mStillRequest, mReqImgReaderOutput);
708 if (ret != ACAMERA_OK) {
709 LOG_ERROR(errorString, "Camera %s add still request output failed. ret %d",
710 mCameraId, ret);
711 return ret;
712 }
713
714 if (mPreviewInited) {
715 ret = ACaptureRequest_addTarget(mStillRequest, mReqPreviewOutput);
716 if (ret != ACAMERA_OK) {
717 LOG_ERROR(errorString,
718 "Camera %s add still request preview output failed. ret %d",
719 mCameraId, ret);
720 return ret;
721 }
722 }
723 } else {
724 ALOGI("AImageReader not inited. Will not create still request!");
725 }
726
727 return ACAMERA_OK;
728 }
729
startPreview()730 camera_status_t startPreview() {
731 if (mSession == nullptr || mPreviewRequest == nullptr) {
732 ALOGE("Testcase cannot start preview: session %p, preview request %p",
733 mSession, mPreviewRequest);
734 return ACAMERA_ERROR_UNKNOWN;
735 }
736 int previewSeqId;
737 return ACameraCaptureSession_setRepeatingRequest(
738 mSession, nullptr, 1, &mPreviewRequest, &previewSeqId);
739 }
740
takePicture()741 camera_status_t takePicture() {
742 if (mSession == nullptr || mStillRequest == nullptr) {
743 ALOGE("Testcase cannot take picture: session %p, still request %p",
744 mSession, mStillRequest);
745 return ACAMERA_ERROR_UNKNOWN;
746 }
747 int seqId;
748 return ACameraCaptureSession_capture(
749 mSession, nullptr, 1, &mStillRequest, &seqId);
750 }
751
getReaderImageCount()752 int getReaderImageCount() {
753 return mReaderListener.onImageAvailableCount();
754 }
755
resetWithErrorLog()756 camera_status_t resetWithErrorLog() {
757 camera_status_t ret;
758
759 mReaderListener.reset();
760 closeSession();
761
762 for (int i = 0; i < 50; i++) {
763 usleep(100000); // sleep 100ms
764 if (mSessionListener.isClosed()) {
765 ALOGI("Session take ~%d ms to close", i*100);
766 break;
767 }
768 }
769
770 if (!mSessionListener.isClosed() || mSessionListener.onClosedCount() != 1) {
771 LOG_ERROR(errorString,
772 "Session for camera %s close error. isClosde %d close count %d",
773 mCameraId, mSessionListener.isClosed(), mSessionListener.onClosedCount());
774 return ACAMERA_ERROR_UNKNOWN;
775 }
776 mSessionListener.reset();
777
778 ret = closeCamera();
779 if (ret != ACAMERA_OK) {
780 LOG_ERROR(errorString, "Close camera device %s failure. ret %d", mCameraId, ret);
781 return ret;
782 }
783
784 resetCamera();
785 return ACAMERA_OK;
786 }
787
setDumpFilePathBase(const char * path)788 void setDumpFilePathBase(const char* path) {
789 mReaderListener.setDumpFilePathBase(path);
790 }
791
getSessionListener()792 CaptureSessionListener* getSessionListener() {
793 return &mSessionListener;
794 }
795
796 private:
createManager()797 ACameraManager* createManager() {
798 if (!mCameraManager) {
799 mCameraManager = ACameraManager_create();
800 }
801 return mCameraManager;
802 }
803
804 CameraServiceListener mServiceListener;
805 ACameraManager_AvailabilityCallbacks mServiceCb {
806 &mServiceListener,
807 CameraServiceListener::onAvailable,
808 CameraServiceListener::onUnavailable
809 };
810 CameraDeviceListener mDeviceListener;
811 ACameraDevice_StateCallbacks mDeviceCb {
812 &mDeviceListener,
813 CameraDeviceListener::onDisconnected,
814 CameraDeviceListener::onError
815 };
816 CaptureSessionListener mSessionListener;
817 ACameraCaptureSession_stateCallbacks mSessionCb {
818 &mSessionListener,
819 CaptureSessionListener::onClosed,
820 CaptureSessionListener::onReady,
821 CaptureSessionListener::onActive
822 };
823
824 // TODO: capture listeners
825 ImageReaderListener mReaderListener;
826 AImageReader_ImageListener mReaderCb {
827 &mReaderListener,
828 ImageReaderListener::onImageAvailable
829 };
830
831 ACameraIdList* mCameraIdList = nullptr;
832 ACameraDevice* mDevice = nullptr;
833 AImageReader* mImgReader = nullptr;
834 ANativeWindow* mImgReaderAnw = nullptr;
835 ANativeWindow* mPreviewAnw = nullptr;
836 ACameraManager* mCameraManager = nullptr;
837 ACaptureSessionOutputContainer* mOutputs = nullptr;
838 ACaptureSessionOutput* mPreviewOutput = nullptr;
839 ACaptureSessionOutput* mImgReaderOutput = nullptr;
840 ACameraCaptureSession* mSession = nullptr;
841 ACaptureRequest* mPreviewRequest = nullptr;
842 ACaptureRequest* mStillRequest = nullptr;
843 ACameraOutputTarget* mReqPreviewOutput = nullptr;
844 ACameraOutputTarget* mReqImgReaderOutput = nullptr;
845 const char* mCameraId;
846
847 bool mMgrInited = false; // cameraId, serviceListener
848 bool mImgReaderInited = false;
849 bool mPreviewInited = false;
850 };
851
throwAssertionError(JNIEnv * env,const char * message)852 jint throwAssertionError(JNIEnv* env, const char* message)
853 {
854 jclass assertionClass;
855 const char* className = "junit/framework/AssertionFailedError";
856
857 assertionClass = env->FindClass(className);
858 if (assertionClass == nullptr) {
859 ALOGE("Native throw error: cannot find class %s", className);
860 return -1;
861 }
862 return env->ThrowNew(assertionClass, message);
863 }
864
865 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetAndCloseNative(JNIEnv * env,jclass)866 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
867 testCameraManagerGetAndCloseNative(
868 JNIEnv* env, jclass /*clazz*/) {
869 bool pass = false;
870 ALOGV("%s", __FUNCTION__);
871 ACameraManager* cameraManager2 = nullptr;
872 ACameraManager* cameraManager3 = nullptr;
873 ACameraManager* cameraManager4 = nullptr;
874 camera_status_t ret = ACAMERA_OK;
875 ACameraManager* cameraManager = ACameraManager_create();
876 if (cameraManager == nullptr) {
877 LOG_ERROR(errorString, "ACameraManager_create returns nullptr");
878 goto cleanup;
879 }
880 ACameraManager_delete(cameraManager);
881 cameraManager = nullptr;
882
883 // Test get/close multiple instances
884 cameraManager = ACameraManager_create();
885 cameraManager2 = ACameraManager_create();
886 if (cameraManager2 == nullptr) {
887 LOG_ERROR(errorString, "ACameraManager_create 2 returns nullptr");
888 goto cleanup;
889 }
890 ACameraManager_delete(cameraManager);
891 cameraManager = nullptr;
892 cameraManager3 = ACameraManager_create();
893 if (cameraManager3 == nullptr) {
894 LOG_ERROR(errorString, "ACameraManager_create 3 returns nullptr");
895 goto cleanup;
896 }
897 cameraManager4 = ACameraManager_create();
898 if (cameraManager4 == nullptr) {
899 LOG_ERROR(errorString, "ACameraManager_create 4 returns nullptr");
900 goto cleanup;
901 }
902 ACameraManager_delete(cameraManager3);
903 ACameraManager_delete(cameraManager2);
904 ACameraManager_delete(cameraManager4);
905
906 pass = true;
907 cleanup:
908 if (cameraManager) {
909 ACameraManager_delete(cameraManager);
910 }
911 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
912 if (!pass) {
913 throwAssertionError(env, errorString);
914 }
915 return pass;
916 }
917
918 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerGetCameraIdsNative(JNIEnv * env,jclass)919 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
920 testCameraManagerGetCameraIdsNative(
921 JNIEnv* env, jclass /*clazz*/) {
922 ALOGV("%s", __FUNCTION__);
923 bool pass = false;
924 ACameraManager* mgr = ACameraManager_create();
925 ACameraIdList *cameraIdList = nullptr;
926 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
927 if (ret != ACAMERA_OK || cameraIdList == nullptr) {
928 LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
929 ret, cameraIdList);
930 goto cleanup;
931 }
932 ALOGI("Number of cameras: %d", cameraIdList->numCameras);
933 for (int i = 0; i < cameraIdList->numCameras; i++) {
934 ALOGI("Camera ID: %s", cameraIdList->cameraIds[i]);
935 }
936 ACameraManager_deleteCameraIdList(cameraIdList);
937 cameraIdList = nullptr;
938
939 pass = true;
940 cleanup:
941 if (mgr) {
942 ACameraManager_delete(mgr);
943 }
944 if (cameraIdList) {
945 ACameraManager_deleteCameraIdList(cameraIdList);
946 }
947 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "fail");
948 if (!pass) {
949 throwAssertionError(env, errorString);
950 }
951 return pass;
952 }
953
954 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerAvailabilityCallbackNative(JNIEnv * env,jclass)955 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
956 testCameraManagerAvailabilityCallbackNative(
957 JNIEnv* env, jclass /*clazz*/) {
958 ALOGV("%s", __FUNCTION__);
959 bool pass = false;
960 ACameraManager* mgr = ACameraManager_create();
961 ACameraIdList *cameraIdList = nullptr;
962 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
963 int numCameras = cameraIdList->numCameras;
964 CameraServiceListener listener;
965 ACameraManager_AvailabilityCallbacks cbs {
966 &listener,
967 CameraServiceListener::onAvailable,
968 CameraServiceListener::onUnavailable};
969 ret = ACameraManager_registerAvailabilityCallback(mgr, &cbs);
970 if (ret != ACAMERA_OK) {
971 LOG_ERROR(errorString, "Register availability callback failed: ret %d", ret);
972 goto cleanup;
973 }
974 sleep(1); // sleep a second to give some time for callbacks to happen
975
976 // Should at least get onAvailable for each camera once
977 if (listener.getAvailableCount() < numCameras) {
978 LOG_ERROR(errorString, "Expect at least %d available callback but only got %d",
979 numCameras, listener.getAvailableCount());
980 goto cleanup;
981 }
982
983 ret = ACameraManager_unregisterAvailabilityCallback(mgr, &cbs);
984 if (ret != ACAMERA_OK) {
985 LOG_ERROR(errorString, "Unregister availability callback failed: ret %d", ret);
986 goto cleanup;
987 }
988 pass = true;
989 cleanup:
990 if (cameraIdList) {
991 ACameraManager_deleteCameraIdList(cameraIdList);
992 }
993 if (mgr) {
994 ACameraManager_delete(mgr);
995 }
996 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
997 if (!pass) {
998 throwAssertionError(env, errorString);
999 }
1000 return pass;
1001 }
1002
1003 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraManagerTest_testCameraManagerCharacteristicsNative(JNIEnv * env,jclass)1004 Java_android_hardware_camera2_cts_NativeCameraManagerTest_\
1005 testCameraManagerCharacteristicsNative(
1006 JNIEnv* env, jclass /*clazz*/) {
1007 ALOGV("%s", __FUNCTION__);
1008 bool pass = false;
1009 ACameraManager* mgr = ACameraManager_create();
1010 ACameraIdList *cameraIdList = nullptr;
1011 ACameraMetadata* chars = nullptr;
1012 int numCameras = 0;
1013 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1014 if (ret != ACAMERA_OK || cameraIdList == nullptr) {
1015 LOG_ERROR(errorString, "Get camera id list failed: ret %d, cameraIdList %p",
1016 ret, cameraIdList);
1017 goto cleanup;
1018 }
1019 numCameras = cameraIdList->numCameras;
1020
1021 for (int i = 0; i < numCameras; i++) {
1022 ret = ACameraManager_getCameraCharacteristics(
1023 mgr, cameraIdList->cameraIds[i], &chars);
1024 if (ret != ACAMERA_OK) {
1025 LOG_ERROR(errorString, "Get camera characteristics failed: ret %d", ret);
1026 goto cleanup;
1027 }
1028
1029 int32_t numTags = 0;
1030 const uint32_t* tags = nullptr;
1031 ret = ACameraMetadata_getAllTags(chars, &numTags, &tags);
1032 if (ret != ACAMERA_OK) {
1033 LOG_ERROR(errorString, "Get camera characteristics tags failed: ret %d", ret);
1034 goto cleanup;
1035 }
1036
1037 for (int tid = 0; tid < numTags; tid++) {
1038 uint32_t tagId = tags[tid];
1039 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
1040 uint32_t sectionId = tagId >> 16;
1041 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
1042 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
1043 goto cleanup;
1044 }
1045 }
1046
1047 ACameraMetadata_const_entry entry;
1048 ret = ACameraMetadata_getConstEntry(chars, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
1049 if (ret != ACAMERA_OK) {
1050 LOG_ERROR(errorString, "Get const available capabilities key failed. ret %d", ret);
1051 goto cleanup;
1052 }
1053
1054 // Check the entry is actually legit
1055 if (entry.tag != ACAMERA_REQUEST_AVAILABLE_CAPABILITIES ||
1056 entry.count == 0 || entry.type != ACAMERA_TYPE_BYTE || entry.data.i32 == nullptr) {
1057 LOG_ERROR(errorString,
1058 "Bad available capabilities key: tag: %d (expected %d), count %u (expect > 0), "
1059 "type %d (expected %d), data %p (expected not null)",
1060 entry.tag, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, entry.count,
1061 entry.type, ACAMERA_TYPE_BYTE, entry.data.i32);
1062 goto cleanup;
1063 }
1064 // All camera supports BC except depth only cameras
1065 bool supportBC = false, supportDepth = false;
1066 for (uint32_t i = 0; i < entry.count; i++) {
1067 if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1068 supportBC = true;
1069 }
1070 if (entry.data.u8[i] == ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
1071 supportDepth = true;
1072 }
1073 }
1074 if (!(supportBC || supportDepth)) {
1075 LOG_ERROR(errorString, "Error: camera device %s does not support either BC or DEPTH",
1076 cameraIdList->cameraIds[i]);
1077 goto cleanup;
1078 }
1079
1080 // Check get unknown value fails
1081 uint32_t badTag = (uint32_t) ACAMERA_VENDOR_START - 1;
1082 ret = ACameraMetadata_getConstEntry(chars, badTag, &entry);
1083 if (ret == ACAMERA_OK) {
1084 LOG_ERROR(errorString, "Error: get unknown tag should fail!");
1085 goto cleanup;
1086 }
1087
1088 ACameraMetadata_free(chars);
1089 chars = nullptr;
1090 }
1091
1092 pass = true;
1093 cleanup:
1094 if (chars) {
1095 ACameraMetadata_free(chars);
1096 }
1097 ACameraManager_deleteCameraIdList(cameraIdList);
1098 ACameraManager_delete(mgr);
1099 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1100 if (!pass) {
1101 throwAssertionError(env, errorString);
1102 }
1103 return pass;
1104 }
1105
1106 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceOpenAndCloseNative(JNIEnv * env,jclass)1107 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1108 testCameraDeviceOpenAndCloseNative(
1109 JNIEnv* env, jclass /*clazz*/) {
1110 ALOGV("%s", __FUNCTION__);
1111 int numCameras = 0;
1112 bool pass = false;
1113 PreviewTestCase testCase;
1114
1115 camera_status_t ret = testCase.initWithErrorLog();
1116 if (ret != ACAMERA_OK) {
1117 // Don't log error here. testcase did it
1118 goto cleanup;
1119 }
1120
1121 numCameras = testCase.getNumCameras();
1122 if (numCameras < 0) {
1123 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1124 goto cleanup;
1125 }
1126
1127 for (int i = 0; i < numCameras; i++) {
1128 const char* cameraId = testCase.getCameraId(i);
1129 if (cameraId == nullptr) {
1130 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1131 goto cleanup;
1132 }
1133
1134 ret = testCase.openCamera(cameraId);
1135 if (ret != ACAMERA_OK) {
1136 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1137 goto cleanup;
1138 }
1139
1140 usleep(100000); // sleep to give some time for callbacks to happen
1141
1142 if (testCase.isCameraAvailable(cameraId)) {
1143 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1144 goto cleanup;
1145 }
1146
1147 ret = testCase.closeCamera();
1148 if (ret != ACAMERA_OK) {
1149 LOG_ERROR(errorString, "Close camera device %s failure. ret %d", cameraId, ret);
1150 goto cleanup;
1151 }
1152
1153 usleep(100000); // sleep to give some time for callbacks to happen
1154
1155 if (!testCase.isCameraAvailable(cameraId)) {
1156 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1157 goto cleanup;
1158 }
1159 }
1160
1161 ret = testCase.deInit();
1162 if (ret != ACAMERA_OK) {
1163 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1164 goto cleanup;
1165 }
1166
1167 pass = true;
1168 cleanup:
1169 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1170 if (!pass) {
1171 throwAssertionError(env, errorString);
1172 }
1173 return pass;
1174 }
1175
1176 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceCreateCaptureRequestNative(JNIEnv * env,jclass)1177 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1178 testCameraDeviceCreateCaptureRequestNative(
1179 JNIEnv* env, jclass /*clazz*/) {
1180 ALOGV("%s", __FUNCTION__);
1181 bool pass = false;
1182 ACameraManager* mgr = ACameraManager_create();
1183 ACameraIdList* cameraIdList = nullptr;
1184 ACameraDevice* device = nullptr;
1185 ACaptureRequest* request = nullptr;
1186 ACameraMetadata* chars = nullptr;
1187 camera_status_t ret = ACameraManager_getCameraIdList(mgr, &cameraIdList);
1188
1189 int numCameras = cameraIdList->numCameras;
1190 for (int i = 0; i < numCameras; i++) {
1191 CameraDeviceListener deviceListener;
1192 const char* cameraId = cameraIdList->cameraIds[i];
1193 ACameraDevice_StateCallbacks deviceCb {
1194 &deviceListener,
1195 CameraDeviceListener::onDisconnected,
1196 CameraDeviceListener::onError
1197 };
1198 ret = ACameraManager_openCamera(mgr, cameraId, &deviceCb, &device);
1199 if (ret != ACAMERA_OK) {
1200 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1201 goto cleanup;
1202 }
1203
1204 ret = ACameraManager_getCameraCharacteristics(mgr, cameraId, &chars);
1205 if (ret != ACAMERA_OK || chars == nullptr) {
1206 LOG_ERROR(errorString, "Get camera %s characteristics failure. ret %d, chars %p",
1207 cameraId, ret, chars);
1208 goto cleanup;
1209 }
1210 StaticInfo staticInfo(chars);
1211
1212 for (int t = TEMPLATE_PREVIEW; t <= TEMPLATE_MANUAL; t++) {
1213 ACameraDevice_request_template templateId =
1214 static_cast<ACameraDevice_request_template>(t);
1215 ret = ACameraDevice_createCaptureRequest(device, templateId, &request);
1216 if (ret == ACAMERA_ERROR_INVALID_PARAMETER) {
1217 // template not supported. skip
1218 continue;
1219 }
1220
1221 if (ret != ACAMERA_OK) {
1222 LOG_ERROR(errorString, "Create capture request failed!: ret %d", ret);
1223 goto cleanup;
1224 }
1225
1226 int32_t numTags = 0;
1227 const uint32_t* tags = nullptr;
1228 ret = ACaptureRequest_getAllTags(request, &numTags, &tags);
1229 if (ret != ACAMERA_OK) {
1230 LOG_ERROR(errorString, "Get capture request tags failed: ret %d", ret);
1231 goto cleanup;
1232 }
1233
1234 for (int tid = 0; tid < numTags; tid++) {
1235 uint32_t tagId = tags[tid];
1236 ALOGV("%s capture request contains key %u", __FUNCTION__, tagId);
1237 uint32_t sectionId = tagId >> 16;
1238 if (sectionId >= ACAMERA_SECTION_COUNT && sectionId < ACAMERA_VENDOR) {
1239 LOG_ERROR(errorString, "Unknown tagId %u, sectionId %u", tagId, sectionId);
1240 goto cleanup;
1241 }
1242 }
1243
1244 // try get/set capture request fields
1245 ACameraMetadata_const_entry entry;
1246 ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
1247 if (ret != ACAMERA_OK) {
1248 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
1249 goto cleanup;
1250 }
1251
1252 if (entry.tag != ACAMERA_CONTROL_AE_MODE || entry.type != ACAMERA_TYPE_BYTE ||\
1253 entry.count != 1) {
1254 LOG_ERROR(errorString,
1255 "Bad AE mode key. tag 0x%x (expect 0x%x), type %d (expect %d), "
1256 "count %d (expect %d)",
1257 entry.tag, ACAMERA_CONTROL_AE_MODE, entry.type, ACAMERA_TYPE_BYTE,
1258 entry.count, 1);
1259 goto cleanup;
1260 }
1261 if (t == TEMPLATE_MANUAL) {
1262 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_OFF) {
1263 LOG_ERROR(errorString, "Error: MANUAL template AE mode %d (expect %d)",
1264 entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_OFF);
1265 goto cleanup;
1266 }
1267 // try set AE_MODE_ON
1268 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON;
1269 ret = ACaptureRequest_setEntry_u8(
1270 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
1271 if (ret != ACAMERA_OK) {
1272 LOG_ERROR(errorString,
1273 "Error: Camera %s template %d: update AE mode key fail. ret %d",
1274 cameraId, t, ret);
1275 goto cleanup;
1276 }
1277 ret = ACaptureRequest_getConstEntry(
1278 request, ACAMERA_CONTROL_AE_MODE, &entry);
1279 if (ret != ACAMERA_OK) {
1280 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
1281 goto cleanup;
1282 }
1283 if (entry.data.u8[0] != aeMode) {
1284 LOG_ERROR(errorString,
1285 "Error: AE mode key is not updated. expect %d but get %d",
1286 aeMode, entry.data.u8[0]);
1287 goto cleanup;
1288 }
1289 } else {
1290 if (staticInfo.isColorOutputSupported()) {
1291 if (entry.data.u8[0] != ACAMERA_CONTROL_AE_MODE_ON) {
1292 LOG_ERROR(errorString,
1293 "Error: Template %d has wrong AE mode %d (expect %d)",
1294 t, entry.data.u8[0], ACAMERA_CONTROL_AE_MODE_ON);
1295 goto cleanup;
1296 }
1297 // try set AE_MODE_OFF
1298 if (staticInfo.isCapabilitySupported(
1299 ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
1300 uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF;
1301 ret = ACaptureRequest_setEntry_u8(
1302 request, ACAMERA_CONTROL_AE_MODE, /*count*/ 1, &aeMode);
1303 if (ret != ACAMERA_OK) {
1304 LOG_ERROR(errorString,
1305 "Error: Camera %s template %d: update AE mode key fail. ret %d",
1306 cameraId, t, ret);
1307 goto cleanup;
1308 }
1309 ret = ACaptureRequest_getConstEntry(
1310 request, ACAMERA_CONTROL_AE_MODE, &entry);
1311 if (ret != ACAMERA_OK) {
1312 LOG_ERROR(errorString, "Get AE mode key failed. ret %d", ret);
1313 goto cleanup;
1314 }
1315 if (entry.data.u8[0] != aeMode) {
1316 LOG_ERROR(errorString,
1317 "Error: AE mode key is not updated. expect %d but get %d",
1318 aeMode, entry.data.u8[0]);
1319 goto cleanup;
1320 }
1321 }
1322 }
1323 }
1324 ACaptureRequest_free(request);
1325 request = nullptr;
1326 }
1327
1328 ACameraMetadata_free(chars);
1329 chars = nullptr;
1330 ACameraDevice_close(device);
1331 device = nullptr;
1332 }
1333
1334 pass = true;
1335 cleanup:
1336 if (cameraIdList) {
1337 ACameraManager_deleteCameraIdList(cameraIdList);
1338 }
1339 if (request) {
1340 ACaptureRequest_free(request);
1341 }
1342 if (chars) {
1343 ACameraMetadata_free(chars);
1344 }
1345 if (device) {
1346 ACameraDevice_close(device);
1347 }
1348 if (mgr) {
1349 ACameraManager_delete(mgr);
1350 }
1351 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1352 if (!pass) {
1353 throwAssertionError(env, errorString);
1354 }
1355 return pass;
1356 }
1357
1358 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSessionOpenAndCloseNative(JNIEnv * env,jclass,jobject jPreviewSurface)1359 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1360 testCameraDeviceSessionOpenAndCloseNative(
1361 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
1362 ALOGV("%s", __FUNCTION__);
1363 int numCameras = 0;
1364 bool pass = false;
1365 PreviewTestCase testCase;
1366
1367 camera_status_t ret = testCase.initWithErrorLog();
1368 if (ret != ACAMERA_OK) {
1369 // Don't log error here. testcase did it
1370 goto cleanup;
1371 }
1372
1373 numCameras = testCase.getNumCameras();
1374 if (numCameras < 0) {
1375 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1376 goto cleanup;
1377 }
1378
1379 for (int i = 0; i < numCameras; i++) {
1380 const char* cameraId = testCase.getCameraId(i);
1381 if (cameraId == nullptr) {
1382 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1383 goto cleanup;
1384 }
1385
1386 ret = testCase.openCamera(cameraId);
1387 if (ret != ACAMERA_OK) {
1388 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1389 goto cleanup;
1390 }
1391
1392 usleep(100000); // sleep to give some time for callbacks to happen
1393
1394 if (testCase.isCameraAvailable(cameraId)) {
1395 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1396 goto cleanup;
1397 }
1398
1399 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
1400 if (previewAnw == nullptr) {
1401 LOG_ERROR(errorString, "Null ANW from preview surface!");
1402 goto cleanup;
1403 }
1404
1405 CaptureSessionListener* sessionListener = testCase.getSessionListener();
1406 if (sessionListener == nullptr) {
1407 LOG_ERROR(errorString, "Session listener camera %s is null", cameraId);
1408 goto cleanup;
1409 }
1410
1411 // Try open/close session multiple times
1412 for (int j = 0; j < 5; j++) {
1413 ret = testCase.createCaptureSessionWithLog();
1414 if (ret != ACAMERA_OK) {
1415 // Don't log error here. testcase did it
1416 goto cleanup;
1417 }
1418
1419 usleep(100000); // sleep to give some time for callbacks to happen
1420
1421 if (!sessionListener->isIdle()) {
1422 LOG_ERROR(errorString, "Session for camera %s should be idle right after creation",
1423 cameraId);
1424 goto cleanup;
1425 }
1426
1427 testCase.closeSession();
1428
1429 usleep(100000); // sleep to give some time for callbacks to happen
1430 if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
1431 LOG_ERROR(errorString,
1432 "Session for camera %s close error. isClosde %d close count %d",
1433 cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
1434 goto cleanup;
1435 }
1436 sessionListener->reset();
1437 }
1438
1439 // Try open/close really fast
1440 ret = testCase.createCaptureSessionWithLog();
1441 if (ret != ACAMERA_OK) {
1442 LOG_ERROR(errorString, "Create session for camera %s failed. ret %d",
1443 cameraId, ret);
1444 goto cleanup;
1445 }
1446 testCase.closeSession();
1447 usleep(100000); // sleep to give some time for callbacks to happen
1448 if (!sessionListener->isClosed() || sessionListener->onClosedCount() != 1) {
1449 LOG_ERROR(errorString,
1450 "Session for camera %s close error. isClosde %d close count %d",
1451 cameraId, sessionListener->isClosed(), sessionListener->onClosedCount());
1452 goto cleanup;
1453 }
1454
1455 ret = testCase.resetWithErrorLog();
1456 if (ret != ACAMERA_OK) {
1457 // Don't log error here. testcase did it
1458 goto cleanup;
1459 }
1460
1461 usleep(100000); // sleep to give some time for callbacks to happen
1462
1463 if (!testCase.isCameraAvailable(cameraId)) {
1464 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1465 goto cleanup;
1466 }
1467 }
1468
1469 ret = testCase.deInit();
1470 if (ret != ACAMERA_OK) {
1471 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1472 goto cleanup;
1473 }
1474
1475 pass = true;
1476 cleanup:
1477 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1478 if (!pass) {
1479 throwAssertionError(env, errorString);
1480 }
1481 return pass;
1482 }
1483
1484 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeCameraDeviceTest_testCameraDeviceSimplePreviewNative(JNIEnv * env,jclass,jobject jPreviewSurface)1485 Java_android_hardware_camera2_cts_NativeCameraDeviceTest_\
1486 testCameraDeviceSimplePreviewNative(
1487 JNIEnv* env, jclass /*clazz*/, jobject jPreviewSurface) {
1488 ALOGV("%s", __FUNCTION__);
1489 int numCameras = 0;
1490 bool pass = false;
1491 PreviewTestCase testCase;
1492
1493 camera_status_t ret = testCase.initWithErrorLog();
1494 if (ret != ACAMERA_OK) {
1495 // Don't log error here. testcase did it
1496 goto cleanup;
1497 }
1498
1499 numCameras = testCase.getNumCameras();
1500 if (numCameras < 0) {
1501 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1502 goto cleanup;
1503 }
1504
1505 for (int i = 0; i < numCameras; i++) {
1506 const char* cameraId = testCase.getCameraId(i);
1507 if (cameraId == nullptr) {
1508 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1509 goto cleanup;
1510 }
1511
1512 ret = testCase.openCamera(cameraId);
1513 if (ret != ACAMERA_OK) {
1514 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1515 goto cleanup;
1516 }
1517
1518 usleep(100000); // sleep to give some time for callbacks to happen
1519
1520 if (testCase.isCameraAvailable(cameraId)) {
1521 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1522 goto cleanup;
1523 }
1524
1525 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
1526 if (previewAnw == nullptr) {
1527 LOG_ERROR(errorString, "Null ANW from preview surface!");
1528 goto cleanup;
1529 }
1530
1531 ret = testCase.createCaptureSessionWithLog();
1532 if (ret != ACAMERA_OK) {
1533 // Don't log error here. testcase did it
1534 goto cleanup;
1535 }
1536
1537 ret = testCase.createRequestsWithErrorLog();
1538 if (ret != ACAMERA_OK) {
1539 // Don't log error here. testcase did it
1540 goto cleanup;
1541 }
1542
1543 ret = testCase.startPreview();
1544 if (ret != ACAMERA_OK) {
1545 LOG_ERROR(errorString, "Start preview failed!");
1546 goto cleanup;
1547 }
1548
1549 sleep(3);
1550
1551 ret = testCase.resetWithErrorLog();
1552 if (ret != ACAMERA_OK) {
1553 // Don't log error here. testcase did it
1554 goto cleanup;
1555 }
1556
1557 usleep(100000); // sleep to give some time for callbacks to happen
1558
1559 if (!testCase.isCameraAvailable(cameraId)) {
1560 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1561 goto cleanup;
1562 }
1563 }
1564
1565 ret = testCase.deInit();
1566 if (ret != ACAMERA_OK) {
1567 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1568 goto cleanup;
1569 }
1570
1571 pass = true;
1572 cleanup:
1573 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1574 if (!pass) {
1575 throwAssertionError(env, errorString);
1576 }
1577 return pass;
1578 }
1579
1580 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeImageReaderTest_testJpegNative(JNIEnv * env,jclass,jstring jOutPath)1581 Java_android_hardware_camera2_cts_NativeImageReaderTest_\
1582 testJpegNative(
1583 JNIEnv* env, jclass /*clazz*/, jstring jOutPath) {
1584 ALOGV("%s", __FUNCTION__);
1585 const int NUM_TEST_IMAGES = 10;
1586 const int TEST_WIDTH = 640;
1587 const int TEST_HEIGHT = 480;
1588 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
1589 int numCameras = 0;
1590 bool pass = false;
1591 PreviewTestCase testCase;
1592
1593 const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
1594 testCase.setDumpFilePathBase(outPath);
1595 ALOGI("%s: out path is %s", __FUNCTION__, outPath);
1596
1597 camera_status_t ret = testCase.initWithErrorLog();
1598 if (ret != ACAMERA_OK) {
1599 // Don't log error here. testcase did it
1600 goto cleanup;
1601 }
1602
1603 numCameras = testCase.getNumCameras();
1604 if (numCameras < 0) {
1605 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1606 goto cleanup;
1607 }
1608
1609 for (int i = 0; i < numCameras; i++) {
1610 const char* cameraId = testCase.getCameraId(i);
1611 if (cameraId == nullptr) {
1612 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1613 goto cleanup;
1614 }
1615
1616 ret = testCase.openCamera(cameraId);
1617 if (ret != ACAMERA_OK) {
1618 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1619 goto cleanup;
1620 }
1621
1622 usleep(100000); // sleep to give some time for callbacks to happen
1623
1624 if (testCase.isCameraAvailable(cameraId)) {
1625 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1626 goto cleanup;
1627 }
1628
1629 mediaRet = testCase.initImageReaderWithErrorLog(
1630 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES);
1631 if (mediaRet != AMEDIA_OK) {
1632 // Don't log error here. testcase did it
1633 goto cleanup;
1634 }
1635
1636 ret = testCase.createCaptureSessionWithLog();
1637 if (ret != ACAMERA_OK) {
1638 // Don't log error here. testcase did it
1639 goto cleanup;
1640 }
1641
1642 ret = testCase.createRequestsWithErrorLog();
1643 if (ret != ACAMERA_OK) {
1644 // Don't log error here. testcase did it
1645 goto cleanup;
1646 }
1647
1648 // Do some still capture
1649 for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
1650 ret = testCase.takePicture();
1651 if (ret != ACAMERA_OK) {
1652 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
1653 cameraId, capture, ret);
1654 goto cleanup;
1655 }
1656 }
1657
1658 // wait until all capture finished
1659 for (int i = 0; i < 50; i++) {
1660 usleep(100000); // sleep 100ms
1661 if (testCase.getReaderImageCount() == NUM_TEST_IMAGES) {
1662 ALOGI("Session take ~%d ms to capture %d images",
1663 i*100, NUM_TEST_IMAGES);
1664 break;
1665 }
1666 }
1667
1668 if (testCase.getReaderImageCount() != NUM_TEST_IMAGES) {
1669 LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
1670 cameraId, NUM_TEST_IMAGES, testCase.getReaderImageCount());
1671 goto cleanup;
1672 }
1673
1674 ret = testCase.resetWithErrorLog();
1675 if (ret != ACAMERA_OK) {
1676 // Don't log error here. testcase did it
1677 goto cleanup;
1678 }
1679
1680 usleep(100000); // sleep to give some time for callbacks to happen
1681
1682 if (!testCase.isCameraAvailable(cameraId)) {
1683 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1684 goto cleanup;
1685 }
1686 }
1687
1688 ret = testCase.deInit();
1689 if (ret != ACAMERA_OK) {
1690 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1691 goto cleanup;
1692 }
1693
1694 pass = true;
1695
1696 cleanup:
1697 env->ReleaseStringUTFChars(jOutPath, outPath);
1698 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1699 if (!pass) {
1700 throwAssertionError(env, errorString);
1701 }
1702 return pass;
1703 }
1704
1705
1706 extern "C" jboolean
Java_android_hardware_camera2_cts_NativeStillCaptureTest_testStillCaptureNative(JNIEnv * env,jclass,jstring jOutPath,jobject jPreviewSurface)1707 Java_android_hardware_camera2_cts_NativeStillCaptureTest_\
1708 testStillCaptureNative(
1709 JNIEnv* env, jclass /*clazz*/, jstring jOutPath, jobject jPreviewSurface) {
1710 ALOGV("%s", __FUNCTION__);
1711 const int NUM_TEST_IMAGES = 10;
1712 const int TEST_WIDTH = 640;
1713 const int TEST_HEIGHT = 480;
1714 media_status_t mediaRet = AMEDIA_ERROR_UNKNOWN;
1715 int numCameras = 0;
1716 bool pass = false;
1717 PreviewTestCase testCase;
1718
1719 const char* outPath = env->GetStringUTFChars(jOutPath, nullptr);
1720 testCase.setDumpFilePathBase(outPath);
1721 ALOGI("%s: out path is %s", __FUNCTION__, outPath);
1722
1723 camera_status_t ret = testCase.initWithErrorLog();
1724 if (ret != ACAMERA_OK) {
1725 // Don't log error here. testcase did it
1726 goto cleanup;
1727 }
1728
1729 numCameras = testCase.getNumCameras();
1730 if (numCameras < 0) {
1731 LOG_ERROR(errorString, "Testcase returned negavtive number of cameras: %d", numCameras);
1732 goto cleanup;
1733 }
1734
1735 for (int i = 0; i < numCameras; i++) {
1736 const char* cameraId = testCase.getCameraId(i);
1737 if (cameraId == nullptr) {
1738 LOG_ERROR(errorString, "Testcase returned null camera id for camera %d", i);
1739 goto cleanup;
1740 }
1741
1742 ret = testCase.openCamera(cameraId);
1743 if (ret != ACAMERA_OK) {
1744 LOG_ERROR(errorString, "Open camera device %s failure. ret %d", cameraId, ret);
1745 goto cleanup;
1746 }
1747
1748 usleep(100000); // sleep to give some time for callbacks to happen
1749
1750 if (testCase.isCameraAvailable(cameraId)) {
1751 LOG_ERROR(errorString, "Camera %s should be unavailable now", cameraId);
1752 goto cleanup;
1753 }
1754
1755 mediaRet = testCase.initImageReaderWithErrorLog(
1756 TEST_WIDTH, TEST_HEIGHT, AIMAGE_FORMAT_JPEG, NUM_TEST_IMAGES);
1757 if (mediaRet != AMEDIA_OK) {
1758 // Don't log error here. testcase did it
1759 goto cleanup;
1760 }
1761
1762 ANativeWindow* previewAnw = testCase.initPreviewAnw(env, jPreviewSurface);
1763 if (previewAnw == nullptr) {
1764 LOG_ERROR(errorString, "Null ANW from preview surface!");
1765 goto cleanup;
1766 }
1767
1768 ret = testCase.createCaptureSessionWithLog();
1769 if (ret != ACAMERA_OK) {
1770 // Don't log error here. testcase did it
1771 goto cleanup;
1772 }
1773
1774 ret = testCase.createRequestsWithErrorLog();
1775 if (ret != ACAMERA_OK) {
1776 // Don't log error here. testcase did it
1777 goto cleanup;
1778 }
1779
1780 ret = testCase.startPreview();
1781 if (ret != ACAMERA_OK) {
1782 LOG_ERROR(errorString, "Start preview failed!");
1783 goto cleanup;
1784 }
1785
1786 // Let preview run some time
1787 sleep(3);
1788
1789 // Do some still capture
1790 for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
1791 ret = testCase.takePicture();
1792 if (ret != ACAMERA_OK) {
1793 LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
1794 cameraId, capture, ret);
1795 goto cleanup;
1796 }
1797 }
1798
1799 // wait until all capture finished
1800 for (int i = 0; i < 50; i++) {
1801 usleep(100000); // sleep 100ms
1802 if (testCase.getReaderImageCount() == NUM_TEST_IMAGES) {
1803 ALOGI("Session take ~%d ms to capture %d images",
1804 i*100, NUM_TEST_IMAGES);
1805 break;
1806 }
1807 }
1808
1809 if (testCase.getReaderImageCount() != NUM_TEST_IMAGES) {
1810 LOG_ERROR(errorString, "Camera %s timeout capturing %d images. Got %d",
1811 cameraId, NUM_TEST_IMAGES, testCase.getReaderImageCount());
1812 goto cleanup;
1813 }
1814
1815 ret = testCase.resetWithErrorLog();
1816 if (ret != ACAMERA_OK) {
1817 // Don't log error here. testcase did it
1818 goto cleanup;
1819 }
1820
1821 usleep(100000); // sleep to give some time for callbacks to happen
1822
1823 if (!testCase.isCameraAvailable(cameraId)) {
1824 LOG_ERROR(errorString, "Camera %s should be available now", cameraId);
1825 goto cleanup;
1826 }
1827 }
1828
1829 ret = testCase.deInit();
1830 if (ret != ACAMERA_OK) {
1831 LOG_ERROR(errorString, "Testcase deInit failed: ret %d", ret);
1832 goto cleanup;
1833 }
1834
1835 pass = true;
1836 cleanup:
1837 env->ReleaseStringUTFChars(jOutPath, outPath);
1838 ALOGI("%s %s", __FUNCTION__, pass ? "pass" : "failed");
1839 if (!pass) {
1840 throwAssertionError(env, errorString);
1841 }
1842 return pass;
1843 }
1844
1845