ProCameraTests.cpp revision bfc9915f482520eb9676c6d2dbf7f1ac078d937d
1/* 2 * Copyright (C) 2013 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#include <gtest/gtest.h> 18#include <iostream> 19 20#include <binder/IPCThreadState.h> 21#include <utils/Thread.h> 22 23#include "Camera.h" 24#include "ProCamera.h" 25#include <utils/Vector.h> 26#include <utils/Mutex.h> 27#include <utils/Condition.h> 28 29#include <gui/SurfaceComposerClient.h> 30#include <gui/Surface.h> 31 32#include <system/camera_metadata.h> 33#include <hardware/camera2.h> // for CAMERA2_TEMPLATE_PREVIEW only 34#include <camera/CameraMetadata.h> 35 36#include <camera/ICameraServiceListener.h> 37 38namespace android { 39namespace camera2 { 40namespace tests { 41namespace client { 42 43#define CAMERA_ID 0 44#define TEST_DEBUGGING 0 45 46#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout 47#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead 48 49#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8 50#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16 51 52// defaults for display "test" 53#define TEST_DISPLAY_FORMAT HAL_PIXEL_FORMAT_Y8 54#define TEST_DISPLAY_WIDTH 320 55#define TEST_DISPLAY_HEIGHT 240 56 57#define TEST_CPU_FRAME_COUNT 2 58#define TEST_CPU_HEAP_COUNT 5 59 60#define TEST_FRAME_PROCESSING_DELAY_US 200000 // 200 ms 61 62#if TEST_DEBUGGING 63#define dout std::cerr 64#else 65#define dout if (0) std::cerr 66#endif 67 68#define EXPECT_OK(x) EXPECT_EQ(OK, (x)) 69#define ASSERT_OK(x) ASSERT_EQ(OK, (x)) 70 71class ProCameraTest; 72 73struct ServiceListener : public BnCameraServiceListener { 74 75 ServiceListener() : 76 mLatestStatus(STATUS_UNKNOWN), 77 mPrevStatus(STATUS_UNKNOWN) 78 { 79 } 80 81 void onStatusChanged(Status status, int32_t cameraId) { 82 dout << "On status changed: 0x" << std::hex 83 << status << " cameraId " << cameraId 84 << std::endl; 85 86 Mutex::Autolock al(mMutex); 87 88 mLatestStatus = status; 89 mCondition.broadcast(); 90 } 91 92 status_t waitForStatusChange(Status& newStatus) { 93 Mutex::Autolock al(mMutex); 94 95 if (mLatestStatus != mPrevStatus) { 96 newStatus = mLatestStatus; 97 mPrevStatus = mLatestStatus; 98 return OK; 99 } 100 101 status_t stat = mCondition.waitRelative(mMutex, 102 TEST_LISTENER_TIMEOUT); 103 104 if (stat == OK) { 105 newStatus = mLatestStatus; 106 mPrevStatus = mLatestStatus; 107 } 108 109 return stat; 110 } 111 112 Condition mCondition; 113 Mutex mMutex; 114 115 Status mLatestStatus; 116 Status mPrevStatus; 117}; 118 119enum ProEvent { 120 UNKNOWN, 121 ACQUIRED, 122 RELEASED, 123 STOLEN, 124 BUFFER_RECEIVED, 125 RESULT_RECEIVED, 126}; 127 128inline int ProEvent_Mask(ProEvent e) { 129 return (1 << static_cast<int>(e)); 130} 131 132typedef Vector<ProEvent> EventList; 133 134class ProCameraTestThread : public Thread 135{ 136public: 137 ProCameraTestThread() { 138 } 139 140 virtual bool threadLoop() { 141 mProc = ProcessState::self(); 142 mProc->startThreadPool(); 143 144 IPCThreadState *ptr = IPCThreadState::self(); 145 146 ptr->joinThreadPool(); 147 148 return false; 149 } 150 151 sp<ProcessState> mProc; 152}; 153 154class ProCameraTestListener : public ProCameraListener { 155 156public: 157 static const int EVENT_MASK_ALL = 0xFFFFFFFF; 158 159 ProCameraTestListener() { 160 mEventMask = EVENT_MASK_ALL; 161 } 162 163 status_t WaitForEvent() { 164 Mutex::Autolock cal(mConditionMutex); 165 166 { 167 Mutex::Autolock al(mListenerMutex); 168 169 if (mProEventList.size() > 0) { 170 return OK; 171 } 172 } 173 174 return mListenerCondition.waitRelative(mConditionMutex, 175 TEST_LISTENER_TIMEOUT); 176 } 177 178 /* Read events into out. Existing queue is flushed */ 179 void ReadEvents(EventList& out) { 180 Mutex::Autolock al(mListenerMutex); 181 182 for (size_t i = 0; i < mProEventList.size(); ++i) { 183 out.push(mProEventList[i]); 184 } 185 186 mProEventList.clear(); 187 } 188 189 /** 190 * Dequeue 1 event from the event queue. 191 * Returns UNKNOWN if queue is empty 192 */ 193 ProEvent ReadEvent() { 194 Mutex::Autolock al(mListenerMutex); 195 196 if (mProEventList.size() == 0) { 197 return UNKNOWN; 198 } 199 200 ProEvent ev = mProEventList[0]; 201 mProEventList.removeAt(0); 202 203 return ev; 204 } 205 206 void SetEventMask(int eventMask) { 207 Mutex::Autolock al(mListenerMutex); 208 mEventMask = eventMask; 209 } 210 211private: 212 void QueueEvent(ProEvent ev) { 213 bool eventAdded = false; 214 { 215 Mutex::Autolock al(mListenerMutex); 216 217 if (ProEvent_Mask(ev) & mEventMask) { 218 mProEventList.push(ev); 219 eventAdded = true; 220 } 221 } 222 223 if (eventAdded) { 224 mListenerCondition.broadcast(); 225 } 226 } 227 228protected: 229 230 ////////////////////////////////////////////////// 231 ///////// ProCameraListener ////////////////////// 232 ////////////////////////////////////////////////// 233 234 235 // Lock has been acquired. Write operations now available. 236 virtual void onLockAcquired() { 237 QueueEvent(ACQUIRED); 238 } 239 // Lock has been released with exclusiveUnlock 240 virtual void onLockReleased() { 241 QueueEvent(RELEASED); 242 } 243 244 // Lock has been stolen by another client. 245 virtual void onLockStolen() { 246 QueueEvent(STOLEN); 247 } 248 249 // Lock free. 250 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) { 251 252 dout << "Trigger notify: " << ext1 << " " << ext2 253 << " " << ext3 << std::endl; 254 } 255 256 virtual void onBufferReceived(int streamId, 257 const CpuConsumer::LockedBuffer& buf) { 258 259 dout << "Buffer received on streamId = " << streamId << 260 ", dataPtr = " << (void*)buf.data << 261 ", timestamp = " << buf.timestamp << std::endl; 262 263 QueueEvent(BUFFER_RECEIVED); 264 265 } 266 virtual void onResultReceived(int32_t frameId, 267 camera_metadata* request) { 268 dout << "Result received frameId = " << frameId 269 << ", requestPtr = " << (void*)request << std::endl; 270 QueueEvent(RESULT_RECEIVED); 271 free_camera_metadata(request); 272 } 273 274 // TODO: remove 275 276 virtual void notify(int32_t , int32_t , int32_t ) {} 277 virtual void postData(int32_t , const sp<IMemory>& , 278 camera_frame_metadata_t *) {} 279 virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {} 280 281 282 Vector<ProEvent> mProEventList; 283 Mutex mListenerMutex; 284 Mutex mConditionMutex; 285 Condition mListenerCondition; 286 int mEventMask; 287}; 288 289class ProCameraTest : public ::testing::Test { 290 291public: 292 ProCameraTest() { 293 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS"); 294 if (displaySecsEnv != NULL) { 295 mDisplaySecs = atoi(displaySecsEnv); 296 if (mDisplaySecs < 0) { 297 mDisplaySecs = 0; 298 } 299 } else { 300 mDisplaySecs = 0; 301 } 302 303 char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT"); 304 if (displayFmtEnv != NULL) { 305 mDisplayFmt = FormatFromString(displayFmtEnv); 306 } else { 307 mDisplayFmt = TEST_DISPLAY_FORMAT; 308 } 309 310 char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH"); 311 if (displayWidthEnv != NULL) { 312 mDisplayW = atoi(displayWidthEnv); 313 if (mDisplayW < 0) { 314 mDisplayW = 0; 315 } 316 } else { 317 mDisplayW = TEST_DISPLAY_WIDTH; 318 } 319 320 char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT"); 321 if (displayHeightEnv != NULL) { 322 mDisplayH = atoi(displayHeightEnv); 323 if (mDisplayH < 0) { 324 mDisplayH = 0; 325 } 326 } else { 327 mDisplayH = TEST_DISPLAY_HEIGHT; 328 } 329 } 330 331 static void SetUpTestCase() { 332 // Binder Thread Pool Initialization 333 mTestThread = new ProCameraTestThread(); 334 mTestThread->run("ProCameraTestThread"); 335 } 336 337 virtual void SetUp() { 338 mCamera = ProCamera::connect(CAMERA_ID); 339 ASSERT_NE((void*)NULL, mCamera.get()); 340 341 mListener = new ProCameraTestListener(); 342 mCamera->setListener(mListener); 343 } 344 345 virtual void TearDown() { 346 ASSERT_NE((void*)NULL, mCamera.get()); 347 mCamera->disconnect(); 348 } 349 350protected: 351 sp<ProCamera> mCamera; 352 sp<ProCameraTestListener> mListener; 353 354 static sp<Thread> mTestThread; 355 356 int mDisplaySecs; 357 int mDisplayFmt; 358 int mDisplayW; 359 int mDisplayH; 360 361 sp<SurfaceComposerClient> mComposerClient; 362 sp<SurfaceControl> mSurfaceControl; 363 364 sp<SurfaceComposerClient> mDepthComposerClient; 365 sp<SurfaceControl> mDepthSurfaceControl; 366 367 int getSurfaceWidth() { 368 return 512; 369 } 370 int getSurfaceHeight() { 371 return 512; 372 } 373 374 void createOnScreenSurface(sp<Surface>& surface) { 375 mComposerClient = new SurfaceComposerClient; 376 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); 377 378 mSurfaceControl = mComposerClient->createSurface( 379 String8("ProCameraTest StreamingImage Surface"), 380 getSurfaceWidth(), getSurfaceHeight(), 381 PIXEL_FORMAT_RGB_888, 0); 382 383 mSurfaceControl->setPosition(0, 0); 384 385 ASSERT_TRUE(mSurfaceControl != NULL); 386 ASSERT_TRUE(mSurfaceControl->isValid()); 387 388 SurfaceComposerClient::openGlobalTransaction(); 389 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF)); 390 ASSERT_EQ(NO_ERROR, mSurfaceControl->show()); 391 SurfaceComposerClient::closeGlobalTransaction(); 392 393 sp<ANativeWindow> window = mSurfaceControl->getSurface(); 394 surface = mSurfaceControl->getSurface(); 395 396 ASSERT_NE((void*)NULL, surface.get()); 397 } 398 399 void createDepthOnScreenSurface(sp<Surface>& surface) { 400 mDepthComposerClient = new SurfaceComposerClient; 401 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck()); 402 403 mDepthSurfaceControl = mDepthComposerClient->createSurface( 404 String8("ProCameraTest StreamingImage Surface"), 405 getSurfaceWidth(), getSurfaceHeight(), 406 PIXEL_FORMAT_RGB_888, 0); 407 408 mDepthSurfaceControl->setPosition(640, 0); 409 410 ASSERT_TRUE(mDepthSurfaceControl != NULL); 411 ASSERT_TRUE(mDepthSurfaceControl->isValid()); 412 413 SurfaceComposerClient::openGlobalTransaction(); 414 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF)); 415 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show()); 416 SurfaceComposerClient::closeGlobalTransaction(); 417 418 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface(); 419 surface = mDepthSurfaceControl->getSurface(); 420 421 ASSERT_NE((void*)NULL, surface.get()); 422 } 423 424 template <typename T> 425 static bool ExistsItem(T needle, T* array, size_t count) { 426 if (!array) { 427 return false; 428 } 429 430 for (size_t i = 0; i < count; ++i) { 431 if (array[i] == needle) { 432 return true; 433 } 434 } 435 return false; 436 } 437 438 439 static int FormatFromString(const char* str) { 440 std::string s(str); 441 442#define CMP_STR(x, y) \ 443 if (s == #x) return HAL_PIXEL_FORMAT_ ## y; 444#define CMP_STR_SAME(x) CMP_STR(x, x) 445 446 CMP_STR_SAME( Y16); 447 CMP_STR_SAME( Y8); 448 CMP_STR_SAME( YV12); 449 CMP_STR(NV16, YCbCr_422_SP); 450 CMP_STR(NV21, YCrCb_420_SP); 451 CMP_STR(YUY2, YCbCr_422_I); 452 CMP_STR(RAW, RAW_SENSOR); 453 CMP_STR(RGBA, RGBA_8888); 454 455 std::cerr << "Unknown format string " << str << std::endl; 456 return -1; 457 458 } 459 460 /** 461 * Creating a streaming request for these output streams from a template, 462 * and submit it 463 */ 464 void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) { 465 466 ASSERT_NE((void*)NULL, streamIds); 467 ASSERT_LT(0u, count); 468 469 camera_metadata_t *requestTmp = NULL; 470 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 471 /*out*/&requestTmp)); 472 ASSERT_NE((void*)NULL, requestTmp); 473 CameraMetadata request(requestTmp); 474 475 // set the output streams. default is empty 476 477 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 478 request.update(tag, streamIds, count); 479 480 requestTmp = request.release(); 481 482 if (requestCount < 0) { 483 EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true)); 484 } else { 485 for (int i = 0; i < requestCount; ++i) { 486 EXPECT_OK(mCamera->submitRequest(requestTmp, 487 /*streaming*/false)); 488 } 489 } 490 request.acquire(requestTmp); 491 } 492}; 493 494sp<Thread> ProCameraTest::mTestThread; 495 496TEST_F(ProCameraTest, AvailableFormats) { 497 if (HasFatalFailure()) { 498 return; 499 } 500 501 CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID); 502 ASSERT_FALSE(staticInfo.isEmpty()); 503 504 uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS); 505 EXPECT_TRUE(staticInfo.exists(tag)); 506 camera_metadata_entry_t entry = staticInfo.find(tag); 507 508 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12, 509 entry.data.i32, entry.count)); 510 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP, 511 entry.data.i32, entry.count)); 512} 513 514// test around exclusiveTryLock (immediate locking) 515TEST_F(ProCameraTest, LockingImmediate) { 516 517 if (HasFatalFailure()) { 518 return; 519 } 520 521 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) | 522 ProEvent_Mask(STOLEN) | 523 ProEvent_Mask(RELEASED)); 524 525 EXPECT_FALSE(mCamera->hasExclusiveLock()); 526 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 527 // at this point we definitely have the lock 528 529 EXPECT_EQ(OK, mListener->WaitForEvent()); 530 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 531 532 EXPECT_TRUE(mCamera->hasExclusiveLock()); 533 EXPECT_EQ(OK, mCamera->exclusiveUnlock()); 534 535 EXPECT_EQ(OK, mListener->WaitForEvent()); 536 EXPECT_EQ(RELEASED, mListener->ReadEvent()); 537 538 EXPECT_FALSE(mCamera->hasExclusiveLock()); 539} 540 541// test around exclusiveLock (locking at some future point in time) 542TEST_F(ProCameraTest, LockingAsynchronous) { 543 544 if (HasFatalFailure()) { 545 return; 546 } 547 548 549 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) | 550 ProEvent_Mask(STOLEN) | 551 ProEvent_Mask(RELEASED)); 552 553 // TODO: Add another procamera that has a lock here. 554 // then we can be test that the lock wont immediately be acquired 555 556 EXPECT_FALSE(mCamera->hasExclusiveLock()); 557 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 558 // at this point we definitely have the lock 559 560 EXPECT_EQ(OK, mListener->WaitForEvent()); 561 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 562 563 EXPECT_TRUE(mCamera->hasExclusiveLock()); 564 EXPECT_EQ(OK, mCamera->exclusiveUnlock()); 565 566 EXPECT_EQ(OK, mListener->WaitForEvent()); 567 EXPECT_EQ(RELEASED, mListener->ReadEvent()); 568 569 EXPECT_FALSE(mCamera->hasExclusiveLock()); 570} 571 572// Stream directly to the screen. 573TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) { 574 if (HasFatalFailure()) { 575 return; 576 } 577 578 sp<Surface> surface; 579 if (mDisplaySecs > 0) { 580 createOnScreenSurface(/*out*/surface); 581 } 582 else { 583 dout << "Skipping, will not render to screen" << std::endl; 584 return; 585 } 586 587 int depthStreamId = -1; 588 589 sp<ServiceListener> listener = new ServiceListener(); 590 EXPECT_OK(ProCamera::addServiceListener(listener)); 591 592 ServiceListener::Status currentStatus = ServiceListener::STATUS_AVAILABLE; 593 594 dout << "Will now stream and resume infinitely..." << std::endl; 595 while (true) { 596 597 if (currentStatus == ServiceListener::STATUS_AVAILABLE) { 598 599 EXPECT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt, 600 surface, 601 &depthStreamId)); 602 EXPECT_NE(-1, depthStreamId); 603 604 EXPECT_OK(mCamera->exclusiveTryLock()); 605 606 uint8_t streams[] = { depthStreamId }; 607 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams( 608 streams, 609 /*count*/1)); 610 } 611 612 ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN; 613 614 // TODO: maybe check for getch every once in a while? 615 while (listener->waitForStatusChange(/*out*/stat) != OK); 616 617 if (currentStatus != stat) { 618 if (stat == ServiceListener::STATUS_AVAILABLE) { 619 dout << "Reconnecting to camera" << std::endl; 620 mCamera = ProCamera::connect(CAMERA_ID); 621 } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) { 622 dout << "Disconnecting from camera" << std::endl; 623 mCamera->disconnect(); 624 } else { 625 dout << "Unknown status change " 626 << std::hex << stat << std::endl; 627 } 628 629 currentStatus = stat; 630 } 631 } 632 633 EXPECT_OK(ProCamera::removeServiceListener(listener)); 634 EXPECT_OK(mCamera->deleteStream(depthStreamId)); 635 EXPECT_OK(mCamera->exclusiveUnlock()); 636} 637 638// Stream directly to the screen. 639TEST_F(ProCameraTest, DISABLED_StreamingImageDual) { 640 if (HasFatalFailure()) { 641 return; 642 } 643 sp<Surface> surface; 644 sp<Surface> depthSurface; 645 if (mDisplaySecs > 0) { 646 createOnScreenSurface(/*out*/surface); 647 createDepthOnScreenSurface(/*out*/depthSurface); 648 } 649 650 int streamId = -1; 651 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960, 652 TEST_FORMAT_MAIN, surface, &streamId)); 653 EXPECT_NE(-1, streamId); 654 655 int depthStreamId = -1; 656 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240, 657 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId)); 658 EXPECT_NE(-1, depthStreamId); 659 660 EXPECT_OK(mCamera->exclusiveTryLock()); 661 /* 662 */ 663 /* iterate in a loop submitting requests every frame. 664 * what kind of requests doesnt really matter, just whatever. 665 */ 666 667 // it would probably be better to use CameraMetadata from camera service. 668 camera_metadata_t *request = NULL; 669 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 670 /*out*/&request)); 671 EXPECT_NE((void*)NULL, request); 672 673 /*FIXME: dont need this later, at which point the above should become an 674 ASSERT_NE*/ 675 if(request == NULL) request = allocate_camera_metadata(10, 100); 676 677 // set the output streams to just this stream ID 678 679 // wow what a verbose API. 680 uint8_t allStreams[] = { streamId, depthStreamId }; 681 // IMPORTANT. bad things will happen if its not a uint8. 682 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]); 683 camera_metadata_entry_t entry; 684 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 685 int find = find_camera_metadata_entry(request, tag, &entry); 686 if (find == -ENOENT) { 687 if (add_camera_metadata_entry(request, tag, &allStreams, 688 /*data_count*/streamCount) != OK) { 689 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 690 ASSERT_OK(append_camera_metadata(tmp, request)); 691 free_camera_metadata(request); 692 request = tmp; 693 694 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 695 /*data_count*/streamCount)); 696 } 697 } else { 698 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 699 &allStreams, /*data_count*/streamCount, &entry)); 700 } 701 702 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 703 704 dout << "will sleep now for " << mDisplaySecs << std::endl; 705 sleep(mDisplaySecs); 706 707 free_camera_metadata(request); 708 709 for (int i = 0; i < streamCount; ++i) { 710 EXPECT_OK(mCamera->deleteStream(allStreams[i])); 711 } 712 EXPECT_OK(mCamera->exclusiveUnlock()); 713} 714 715TEST_F(ProCameraTest, CpuConsumerSingle) { 716 if (HasFatalFailure()) { 717 return; 718 } 719 720 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED)); 721 722 int streamId = -1; 723 sp<CpuConsumer> consumer; 724 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240, 725 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 726 EXPECT_NE(-1, streamId); 727 728 EXPECT_OK(mCamera->exclusiveTryLock()); 729 EXPECT_EQ(OK, mListener->WaitForEvent()); 730 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 731 /* iterate in a loop submitting requests every frame. 732 * what kind of requests doesnt really matter, just whatever. 733 */ 734 735 // it would probably be better to use CameraMetadata from camera service. 736 camera_metadata_t *request = NULL; 737 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 738 /*out*/&request)); 739 EXPECT_NE((void*)NULL, request); 740 741 /*FIXME: dont need this later, at which point the above should become an 742 ASSERT_NE*/ 743 if(request == NULL) request = allocate_camera_metadata(10, 100); 744 745 // set the output streams to just this stream ID 746 747 uint8_t allStreams[] = { streamId }; 748 camera_metadata_entry_t entry; 749 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 750 int find = find_camera_metadata_entry(request, tag, &entry); 751 if (find == -ENOENT) { 752 if (add_camera_metadata_entry(request, tag, &allStreams, 753 /*data_count*/1) != OK) { 754 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 755 ASSERT_OK(append_camera_metadata(tmp, request)); 756 free_camera_metadata(request); 757 request = tmp; 758 759 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 760 /*data_count*/1)); 761 } 762 } else { 763 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 764 &allStreams, /*data_count*/1, &entry)); 765 } 766 767 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 768 769 // Consume a couple of frames 770 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 771 EXPECT_EQ(OK, mListener->WaitForEvent()); 772 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent()); 773 } 774 775 // Done: clean up 776 free_camera_metadata(request); 777 EXPECT_OK(mCamera->deleteStream(streamId)); 778 EXPECT_OK(mCamera->exclusiveUnlock()); 779} 780 781TEST_F(ProCameraTest, CpuConsumerDual) { 782 if (HasFatalFailure()) { 783 return; 784 } 785 786 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED)); 787 788 int streamId = -1; 789 sp<CpuConsumer> consumer; 790 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 791 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 792 EXPECT_NE(-1, streamId); 793 794 int depthStreamId = -1; 795 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240, 796 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId)); 797 EXPECT_NE(-1, depthStreamId); 798 799 EXPECT_OK(mCamera->exclusiveTryLock()); 800 /* 801 */ 802 /* iterate in a loop submitting requests every frame. 803 * what kind of requests doesnt really matter, just whatever. 804 */ 805 806 // it would probably be better to use CameraMetadata from camera service. 807 camera_metadata_t *request = NULL; 808 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 809 /*out*/&request)); 810 EXPECT_NE((void*)NULL, request); 811 812 if(request == NULL) request = allocate_camera_metadata(10, 100); 813 814 // set the output streams to just this stream ID 815 816 // wow what a verbose API. 817 uint8_t allStreams[] = { streamId, depthStreamId }; 818 size_t streamCount = 2; 819 camera_metadata_entry_t entry; 820 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 821 int find = find_camera_metadata_entry(request, tag, &entry); 822 if (find == -ENOENT) { 823 if (add_camera_metadata_entry(request, tag, &allStreams, 824 /*data_count*/streamCount) != OK) { 825 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 826 ASSERT_OK(append_camera_metadata(tmp, request)); 827 free_camera_metadata(request); 828 request = tmp; 829 830 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 831 /*data_count*/streamCount)); 832 } 833 } else { 834 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 835 &allStreams, /*data_count*/streamCount, &entry)); 836 } 837 838 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 839 840 // Consume a couple of frames 841 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 842 // stream id 1 843 EXPECT_EQ(OK, mListener->WaitForEvent()); 844 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent()); 845 846 // stream id 2 847 EXPECT_EQ(OK, mListener->WaitForEvent()); 848 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent()); 849 850 //TODO: events should be a struct with some data like the stream id 851 } 852 853 // Done: clean up 854 free_camera_metadata(request); 855 EXPECT_OK(mCamera->deleteStream(streamId)); 856 EXPECT_OK(mCamera->exclusiveUnlock()); 857} 858 859TEST_F(ProCameraTest, ResultReceiver) { 860 if (HasFatalFailure()) { 861 return; 862 } 863 864 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED)); 865 //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED 866 // need to filter out events at read time 867 868 int streamId = -1; 869 sp<CpuConsumer> consumer; 870 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 871 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 872 EXPECT_NE(-1, streamId); 873 874 EXPECT_OK(mCamera->exclusiveTryLock()); 875 /* 876 */ 877 /* iterate in a loop submitting requests every frame. 878 * what kind of requests doesnt really matter, just whatever. 879 */ 880 881 camera_metadata_t *request = NULL; 882 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 883 /*out*/&request)); 884 EXPECT_NE((void*)NULL, request); 885 886 /*FIXME*/ 887 if(request == NULL) request = allocate_camera_metadata(10, 100); 888 889 // set the output streams to just this stream ID 890 891 uint8_t allStreams[] = { streamId }; 892 size_t streamCount = 1; 893 camera_metadata_entry_t entry; 894 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 895 int find = find_camera_metadata_entry(request, tag, &entry); 896 if (find == -ENOENT) { 897 if (add_camera_metadata_entry(request, tag, &allStreams, 898 /*data_count*/streamCount) != OK) { 899 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 900 ASSERT_OK(append_camera_metadata(tmp, request)); 901 free_camera_metadata(request); 902 request = tmp; 903 904 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 905 /*data_count*/streamCount)); 906 } 907 } else { 908 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 909 &allStreams, /*data_count*/streamCount, &entry)); 910 } 911 912 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 913 914 // Consume a couple of results 915 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 916 EXPECT_EQ(OK, mListener->WaitForEvent()); 917 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent()); 918 } 919 920 // Done: clean up 921 free_camera_metadata(request); 922 EXPECT_OK(mCamera->deleteStream(streamId)); 923 EXPECT_OK(mCamera->exclusiveUnlock()); 924} 925 926TEST_F(ProCameraTest, WaitForResult) { 927 if (HasFatalFailure()) { 928 return; 929 } 930 931 int streamId = -1; 932 sp<CpuConsumer> consumer; 933 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 934 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 935 EXPECT_NE(-1, streamId); 936 937 EXPECT_OK(mCamera->exclusiveTryLock()); 938 939 uint8_t streams[] = { streamId }; 940 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1)); 941 942 // Consume a couple of results 943 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 944 EXPECT_OK(mCamera->waitForFrameMetadata()); 945 CameraMetadata meta = mCamera->consumeFrameMetadata(); 946 EXPECT_FALSE(meta.isEmpty()); 947 } 948 949 // Done: clean up 950 consumer->abandon(); // since we didn't consume any of the buffers 951 EXPECT_OK(mCamera->deleteStream(streamId)); 952 EXPECT_OK(mCamera->exclusiveUnlock()); 953} 954 955TEST_F(ProCameraTest, WaitForSingleStreamBuffer) { 956 if (HasFatalFailure()) { 957 return; 958 } 959 960 int streamId = -1; 961 sp<CpuConsumer> consumer; 962 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 963 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 964 EXPECT_NE(-1, streamId); 965 966 EXPECT_OK(mCamera->exclusiveTryLock()); 967 968 uint8_t streams[] = { streamId }; 969 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1, 970 /*requests*/TEST_CPU_FRAME_COUNT)); 971 972 // Consume a couple of results 973 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 974 EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId)); 975 976 CpuConsumer::LockedBuffer buf; 977 EXPECT_OK(consumer->lockNextBuffer(&buf)); 978 979 dout << "Buffer synchronously received on streamId = " << streamId << 980 ", dataPtr = " << (void*)buf.data << 981 ", timestamp = " << buf.timestamp << std::endl; 982 983 EXPECT_OK(consumer->unlockBuffer(buf)); 984 } 985 986 // Done: clean up 987 EXPECT_OK(mCamera->deleteStream(streamId)); 988 EXPECT_OK(mCamera->exclusiveUnlock()); 989} 990 991TEST_F(ProCameraTest, WaitForDualStreamBuffer) { 992 if (HasFatalFailure()) { 993 return; 994 } 995 996 const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10; 997 998 // 15 fps 999 int streamId = -1; 1000 sp<CpuConsumer> consumer; 1001 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 1002 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 1003 EXPECT_NE(-1, streamId); 1004 1005 // 30 fps 1006 int depthStreamId = -1; 1007 sp<CpuConsumer> depthConsumer; 1008 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240, 1009 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId)); 1010 EXPECT_NE(-1, depthStreamId); 1011 1012 EXPECT_OK(mCamera->exclusiveTryLock()); 1013 1014 uint8_t streams[] = { streamId, depthStreamId }; 1015 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2, 1016 /*requests*/REQUEST_COUNT)); 1017 1018 // Consume two frames simultaneously. Unsynchronized by timestamps. 1019 for (int i = 0; i < REQUEST_COUNT; ++i) { 1020 1021 // Get the metadata 1022 EXPECT_OK(mCamera->waitForFrameMetadata()); 1023 CameraMetadata meta = mCamera->consumeFrameMetadata(); 1024 EXPECT_FALSE(meta.isEmpty()); 1025 1026 // Get the buffers 1027 1028 EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId)); 1029 1030 /** 1031 * Guaranteed to be able to consume the depth frame, 1032 * since we waited on it. 1033 */ 1034 CpuConsumer::LockedBuffer depthBuffer; 1035 EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer)); 1036 1037 dout << "Depth Buffer synchronously received on streamId = " << 1038 streamId << 1039 ", dataPtr = " << (void*)depthBuffer.data << 1040 ", timestamp = " << depthBuffer.timestamp << std::endl; 1041 1042 EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer)); 1043 1044 1045 /** Consume Greyscale frames if there are any. 1046 * There may not be since it runs at half FPS */ 1047 CpuConsumer::LockedBuffer greyBuffer; 1048 while (consumer->lockNextBuffer(&greyBuffer) == OK) { 1049 1050 dout << "GRAY Buffer synchronously received on streamId = " << 1051 streamId << 1052 ", dataPtr = " << (void*)greyBuffer.data << 1053 ", timestamp = " << greyBuffer.timestamp << std::endl; 1054 1055 EXPECT_OK(consumer->unlockBuffer(greyBuffer)); 1056 } 1057 } 1058 1059 // Done: clean up 1060 EXPECT_OK(mCamera->deleteStream(streamId)); 1061 EXPECT_OK(mCamera->exclusiveUnlock()); 1062} 1063 1064TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) { 1065 if (HasFatalFailure()) { 1066 return; 1067 } 1068 1069 const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT; 1070 1071 int streamId = -1; 1072 sp<CpuConsumer> consumer; 1073 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 1074 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); 1075 EXPECT_NE(-1, streamId); 1076 1077 EXPECT_OK(mCamera->exclusiveTryLock()); 1078 1079 uint8_t streams[] = { streamId }; 1080 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1, 1081 /*requests*/NUM_REQUESTS)); 1082 1083 // Consume a couple of results 1084 for (int i = 0; i < NUM_REQUESTS; ++i) { 1085 int numFrames; 1086 EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0); 1087 1088 // Drop all but the newest framebuffer 1089 EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1)); 1090 1091 dout << "Dropped " << (numFrames - 1) << " frames" << std::endl; 1092 1093 // Skip the counter ahead, don't try to consume these frames again 1094 i += numFrames-1; 1095 1096 // "Consume" the buffer 1097 CpuConsumer::LockedBuffer buf; 1098 EXPECT_OK(consumer->lockNextBuffer(&buf)); 1099 1100 dout << "Buffer synchronously received on streamId = " << streamId << 1101 ", dataPtr = " << (void*)buf.data << 1102 ", timestamp = " << buf.timestamp << std::endl; 1103 1104 // Process at 10fps, stream is at 15fps. 1105 // This means we will definitely fill up the buffer queue with 1106 // extra buffers and need to drop them. 1107 usleep(TEST_FRAME_PROCESSING_DELAY_US); 1108 1109 EXPECT_OK(consumer->unlockBuffer(buf)); 1110 } 1111 1112 // Done: clean up 1113 EXPECT_OK(mCamera->deleteStream(streamId)); 1114 EXPECT_OK(mCamera->exclusiveUnlock()); 1115} 1116 1117 1118 1119//TODO: refactor into separate file 1120TEST_F(ProCameraTest, ServiceListenersSubscribe) { 1121 1122 ASSERT_EQ(4u, sizeof(ServiceListener::Status)); 1123 1124 sp<ServiceListener> listener = new ServiceListener(); 1125 1126 EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener)); 1127 EXPECT_OK(ProCamera::addServiceListener(listener)); 1128 1129 EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener)); 1130 EXPECT_OK(ProCamera::removeServiceListener(listener)); 1131 1132 EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener)); 1133} 1134 1135//TODO: refactor into separate file 1136TEST_F(ProCameraTest, ServiceListenersFunctional) { 1137 1138 sp<ServiceListener> listener = new ServiceListener(); 1139 1140 EXPECT_OK(ProCamera::addServiceListener(listener)); 1141 1142 sp<Camera> cam = Camera::connect(CAMERA_ID, 1143 /*clientPackageName*/String16(), 1144 -1); 1145 EXPECT_NE((void*)NULL, cam.get()); 1146 1147 ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN; 1148 EXPECT_OK(listener->waitForStatusChange(/*out*/stat)); 1149 1150 EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat); 1151 1152 if (cam.get()) { 1153 cam->disconnect(); 1154 } 1155 1156 EXPECT_OK(listener->waitForStatusChange(/*out*/stat)); 1157 EXPECT_EQ(ServiceListener::STATUS_AVAILABLE, stat); 1158 1159 EXPECT_OK(ProCamera::removeServiceListener(listener)); 1160} 1161 1162 1163 1164} 1165} 1166} 1167} 1168 1169