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: 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 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 73 void resetCount() { 74 std::lock_guard<std::mutex> lock(mMutex); 75 mOnAvailableCount = 0; 76 mOnUnavailableCount = 0; 77 return; 78 } 79 80 int getAvailableCount() { 81 std::lock_guard<std::mutex> lock(mMutex); 82 return mOnAvailableCount; 83 } 84 85 int getUnavailableCount() { 86 std::lock_guard<std::mutex> lock(mMutex); 87 return mOnUnavailableCount; 88 } 89 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: 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 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: 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 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 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 191 bool isClosed() { 192 std::lock_guard<std::mutex> lock(mMutex); 193 return mIsClosed; 194 } 195 196 bool isIdle() { 197 std::lock_guard<std::mutex> lock(mMutex); 198 return mIsIdle; 199 } 200 201 bool isInError() { 202 std::lock_guard<std::mutex> lock(mMutex); 203 return mInError; 204 } 205 206 int onClosedCount() { 207 std::lock_guard<std::mutex> lock(mMutex); 208 return mOnClosed; 209 } 210 211 int onReadyCount() { 212 std::lock_guard<std::mutex> lock(mMutex); 213 return mOnReady; 214 } 215 216 int onActiveCount() { 217 std::lock_guard<std::mutex> lock(mMutex); 218 return mOnActive; 219 } 220 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: 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 323 int onImageAvailableCount() { 324 std::lock_guard<std::mutex> lock(mMutex); 325 return mOnImageAvailableCount; 326 } 327 328 void setDumpFilePathBase(const char* path) { 329 std::lock_guard<std::mutex> lock(mMutex); 330 mDumpFilePathBase = path; 331 } 332 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: 348 StaticInfo(ACameraMetadata* chars) : mChars(chars) {} 349 350 bool isColorOutputSupported() { 351 return isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE); 352 } 353 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: 370 ~PreviewTestCase() { 371 resetCamera(); 372 deInit(); 373 if (mCameraManager) { 374 ACameraManager_delete(mCameraManager); 375 mCameraManager = nullptr; 376 } 377 } 378 379 PreviewTestCase() { 380 // create is guaranteed to succeed; 381 createManager(); 382 } 383 384 // Free all resources except camera manager 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 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 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 475 int getNumCameras() { 476 if (!mMgrInited || !mCameraIdList) { 477 return -1; 478 } 479 return mCameraIdList->numCameras; 480 } 481 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 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 498 camera_status_t closeCamera() { 499 camera_status_t ret = ACameraDevice_close(mDevice); 500 mDevice = nullptr; 501 return ret; 502 } 503 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 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 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 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 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 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 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 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 752 int getReaderImageCount() { 753 return mReaderListener.onImageAvailableCount(); 754 } 755 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 788 void setDumpFilePathBase(const char* path) { 789 mReaderListener.setDumpFilePathBase(path); 790 } 791 792 CaptureSessionListener* getSessionListener() { 793 return &mSessionListener; 794 } 795 796 private: 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 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 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 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 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 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, ACAMERA_VENDOR_START, &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 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 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 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 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 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 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