CameraBinderTests.cpp revision 8ca23dca1cd450b4d93e8da1c8bd6f6ee61e2f5f
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 "CameraBinderTests" 19 20#include <binder/IInterface.h> 21#include <binder/IServiceManager.h> 22#include <binder/Parcel.h> 23#include <binder/ProcessState.h> 24#include <utils/Errors.h> 25#include <utils/Log.h> 26#include <utils/List.h> 27#include <utils/String8.h> 28#include <utils/String16.h> 29#include <utils/Condition.h> 30#include <utils/Mutex.h> 31#include <system/graphics.h> 32#include <hardware/gralloc.h> 33 34#include <camera/CameraMetadata.h> 35#include <android/hardware/ICameraService.h> 36#include <android/hardware/ICameraServiceListener.h> 37#include <android/hardware/BnCameraServiceListener.h> 38#include <android/hardware/camera2/ICameraDeviceUser.h> 39#include <android/hardware/camera2/ICameraDeviceCallbacks.h> 40#include <android/hardware/camera2/BnCameraDeviceCallbacks.h> 41#include <camera/camera2/CaptureRequest.h> 42#include <camera/camera2/OutputConfiguration.h> 43#include <camera/camera2/SubmitInfo.h> 44 45#include <gui/BufferItemConsumer.h> 46#include <gui/IGraphicBufferProducer.h> 47#include <gui/Surface.h> 48 49#include <gtest/gtest.h> 50#include <unistd.h> 51#include <stdint.h> 52#include <utility> 53#include <vector> 54#include <map> 55#include <algorithm> 56 57using namespace android; 58 59#define ASSERT_NOT_NULL(x) \ 60 ASSERT_TRUE((x) != nullptr) 61 62#define SETUP_TIMEOUT 2000000000 // ns 63#define IDLE_TIMEOUT 2000000000 // ns 64 65// Stub listener implementation 66class TestCameraServiceListener : public hardware::BnCameraServiceListener { 67 std::map<String16, int32_t> mCameraTorchStatuses; 68 std::map<String16, int32_t> mCameraStatuses; 69 mutable Mutex mLock; 70 mutable Condition mCondition; 71 mutable Condition mTorchCondition; 72public: 73 virtual ~TestCameraServiceListener() {}; 74 75 virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId) { 76 Mutex::Autolock l(mLock); 77 mCameraStatuses[cameraId] = status; 78 mCondition.broadcast(); 79 return binder::Status::ok(); 80 }; 81 82 virtual binder::Status onTorchStatusChanged(int32_t status, const String16& cameraId) { 83 Mutex::Autolock l(mLock); 84 mCameraTorchStatuses[cameraId] = status; 85 mTorchCondition.broadcast(); 86 return binder::Status::ok(); 87 }; 88 89 bool waitForNumCameras(size_t num) const { 90 Mutex::Autolock l(mLock); 91 92 if (mCameraStatuses.size() == num) { 93 return true; 94 } 95 96 while (mCameraStatuses.size() < num) { 97 if (mCondition.waitRelative(mLock, SETUP_TIMEOUT) != OK) { 98 return false; 99 } 100 } 101 return true; 102 }; 103 104 bool waitForTorchState(int32_t status, int32_t cameraId) const { 105 Mutex::Autolock l(mLock); 106 107 const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId))); 108 if (iter != mCameraTorchStatuses.end() && iter->second == status) { 109 return true; 110 } 111 112 bool foundStatus = false; 113 while (!foundStatus) { 114 if (mTorchCondition.waitRelative(mLock, SETUP_TIMEOUT) != OK) { 115 return false; 116 } 117 const auto& iter = 118 mCameraTorchStatuses.find(String16(String8::format("%d", cameraId))); 119 foundStatus = (iter != mCameraTorchStatuses.end() && iter->second == status); 120 } 121 return true; 122 }; 123 124 int32_t getTorchStatus(int32_t cameraId) const { 125 Mutex::Autolock l(mLock); 126 const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId))); 127 if (iter == mCameraTorchStatuses.end()) { 128 return hardware::ICameraServiceListener::TORCH_STATUS_UNKNOWN; 129 } 130 return iter->second; 131 }; 132 133 int32_t getStatus(const String16& cameraId) const { 134 Mutex::Autolock l(mLock); 135 const auto& iter = mCameraStatuses.find(cameraId); 136 if (iter == mCameraStatuses.end()) { 137 return hardware::ICameraServiceListener::STATUS_UNKNOWN; 138 } 139 return iter->second; 140 }; 141}; 142 143// Callback implementation 144class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks { 145public: 146 enum Status { 147 IDLE, 148 ERROR, 149 PREPARED, 150 RUNNING, 151 SENT_RESULT, 152 UNINITIALIZED, 153 REPEATING_REQUEST_ERROR, 154 REQUEST_QUEUE_EMPTY, 155 }; 156 157protected: 158 bool mError; 159 int32_t mLastStatus; 160 mutable std::vector<int32_t> mStatusesHit; 161 mutable Mutex mLock; 162 mutable Condition mStatusCondition; 163public: 164 TestCameraDeviceCallbacks() : mError(false), mLastStatus(UNINITIALIZED) {} 165 166 virtual ~TestCameraDeviceCallbacks() {} 167 168 virtual binder::Status onDeviceError(int errorCode, 169 const CaptureResultExtras& resultExtras) { 170 (void) resultExtras; 171 ALOGE("%s: onDeviceError occurred with: %d", __FUNCTION__, static_cast<int>(errorCode)); 172 Mutex::Autolock l(mLock); 173 mError = true; 174 mLastStatus = ERROR; 175 mStatusesHit.push_back(mLastStatus); 176 mStatusCondition.broadcast(); 177 return binder::Status::ok(); 178 } 179 180 virtual binder::Status onDeviceIdle() { 181 Mutex::Autolock l(mLock); 182 mLastStatus = IDLE; 183 mStatusesHit.push_back(mLastStatus); 184 mStatusCondition.broadcast(); 185 return binder::Status::ok(); 186 } 187 188 virtual binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras, 189 int64_t timestamp) { 190 (void) resultExtras; 191 (void) timestamp; 192 Mutex::Autolock l(mLock); 193 mLastStatus = RUNNING; 194 mStatusesHit.push_back(mLastStatus); 195 mStatusCondition.broadcast(); 196 return binder::Status::ok(); 197 } 198 199 200 virtual binder::Status onResultReceived(const CameraMetadata& metadata, 201 const CaptureResultExtras& resultExtras) { 202 (void) metadata; 203 (void) resultExtras; 204 Mutex::Autolock l(mLock); 205 mLastStatus = SENT_RESULT; 206 mStatusesHit.push_back(mLastStatus); 207 mStatusCondition.broadcast(); 208 return binder::Status::ok(); 209 } 210 211 virtual binder::Status onPrepared(int streamId) { 212 (void) streamId; 213 Mutex::Autolock l(mLock); 214 mLastStatus = PREPARED; 215 mStatusesHit.push_back(mLastStatus); 216 mStatusCondition.broadcast(); 217 return binder::Status::ok(); 218 } 219 220 virtual binder::Status onRepeatingRequestError( 221 int64_t lastFrameNumber, int32_t stoppedSequenceId) { 222 (void) lastFrameNumber; 223 (void) stoppedSequenceId; 224 Mutex::Autolock l(mLock); 225 mLastStatus = REPEATING_REQUEST_ERROR; 226 mStatusesHit.push_back(mLastStatus); 227 mStatusCondition.broadcast(); 228 return binder::Status::ok(); 229 } 230 231 virtual binder::Status onRequestQueueEmpty() { 232 Mutex::Autolock l(mLock); 233 mLastStatus = REQUEST_QUEUE_EMPTY; 234 mStatusesHit.push_back(mLastStatus); 235 mStatusCondition.broadcast(); 236 return binder::Status::ok(); 237 } 238 239 // Test helper functions: 240 241 bool hadError() const { 242 Mutex::Autolock l(mLock); 243 return mError; 244 } 245 246 bool waitForStatus(Status status) const { 247 Mutex::Autolock l(mLock); 248 if (mLastStatus == status) { 249 return true; 250 } 251 252 while (std::find(mStatusesHit.begin(), mStatusesHit.end(), status) 253 == mStatusesHit.end()) { 254 255 if (mStatusCondition.waitRelative(mLock, IDLE_TIMEOUT) != OK) { 256 mStatusesHit.clear(); 257 return false; 258 } 259 } 260 mStatusesHit.clear(); 261 262 return true; 263 264 } 265 266 void clearStatus() const { 267 Mutex::Autolock l(mLock); 268 mStatusesHit.clear(); 269 } 270 271 bool waitForIdle() const { 272 return waitForStatus(IDLE); 273 } 274 275}; 276 277namespace { 278 Mutex gLock; 279 class DeathNotifier : public IBinder::DeathRecipient 280 { 281 public: 282 DeathNotifier() {} 283 284 virtual void binderDied(const wp<IBinder>& /*who*/) { 285 ALOGV("binderDied"); 286 Mutex::Autolock _l(gLock); 287 ALOGW("Camera service died!"); 288 } 289 }; 290 sp<DeathNotifier> gDeathNotifier; 291}; // anonymous namespace 292 293// Exercise basic binder calls for the camera service 294TEST(CameraServiceBinderTest, CheckBinderCameraService) { 295 ProcessState::self()->startThreadPool(); 296 sp<IServiceManager> sm = defaultServiceManager(); 297 sp<IBinder> binder = sm->getService(String16("media.camera")); 298 ASSERT_NOT_NULL(binder); 299 if (gDeathNotifier == NULL) { 300 gDeathNotifier = new DeathNotifier(); 301 } 302 binder->linkToDeath(gDeathNotifier); 303 sp<hardware::ICameraService> service = 304 interface_cast<hardware::ICameraService>(binder); 305 306 binder::Status res; 307 308 int32_t numCameras = 0; 309 res = service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras); 310 EXPECT_TRUE(res.isOk()) << res; 311 EXPECT_LE(0, numCameras); 312 313 // Check listener binder calls 314 sp<TestCameraServiceListener> listener(new TestCameraServiceListener()); 315 std::vector<hardware::CameraStatus> statuses; 316 res = service->addListener(listener, &statuses); 317 EXPECT_TRUE(res.isOk()) << res; 318 319 EXPECT_EQ(numCameras, static_cast<const int>(statuses.size())); 320 321 for (int32_t i = 0; i < numCameras; i++) { 322 String16 cameraId = String16(String8::format("%d", i)); 323 bool isSupported = false; 324 res = service->supportsCameraApi(cameraId, 325 hardware::ICameraService::API_VERSION_2, &isSupported); 326 EXPECT_TRUE(res.isOk()) << res; 327 328 // We only care about binder calls for the Camera2 API. Camera1 is deprecated. 329 if (!isSupported) { 330 continue; 331 } 332 333 // Check metadata binder call 334 CameraMetadata metadata; 335 res = service->getCameraCharacteristics(cameraId, &metadata); 336 EXPECT_TRUE(res.isOk()) << res; 337 EXPECT_FALSE(metadata.isEmpty()); 338 339 // Make sure we're available, or skip device tests otherwise 340 int32_t s = listener->getStatus(cameraId); 341 EXPECT_EQ(::android::hardware::ICameraServiceListener::STATUS_PRESENT, s); 342 if (s != ::android::hardware::ICameraServiceListener::STATUS_PRESENT) { 343 continue; 344 } 345 346 // Check connect binder calls 347 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 348 sp<hardware::camera2::ICameraDeviceUser> device; 349 res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"), 350 hardware::ICameraService::USE_CALLING_UID, /*out*/&device); 351 EXPECT_TRUE(res.isOk()) << res; 352 ASSERT_NE(nullptr, device.get()); 353 device->disconnect(); 354 EXPECT_FALSE(callbacks->hadError()); 355 356 int32_t torchStatus = listener->getTorchStatus(i); 357 if (torchStatus == hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) { 358 // Check torch calls 359 res = service->setTorchMode(cameraId, 360 /*enabled*/true, callbacks); 361 EXPECT_TRUE(res.isOk()) << res; 362 EXPECT_TRUE(listener->waitForTorchState( 363 hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i)); 364 res = service->setTorchMode(cameraId, 365 /*enabled*/false, callbacks); 366 EXPECT_TRUE(res.isOk()) << res; 367 EXPECT_TRUE(listener->waitForTorchState( 368 hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i)); 369 } 370 } 371 372 res = service->removeListener(listener); 373 EXPECT_TRUE(res.isOk()) << res; 374} 375 376// Test fixture for client focused binder tests 377class CameraClientBinderTest : public testing::Test { 378protected: 379 sp<hardware::ICameraService> service; 380 int32_t numCameras; 381 std::vector<std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>> 382 openDeviceList; 383 sp<TestCameraServiceListener> serviceListener; 384 385 std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>> 386 openNewDevice(const String16& deviceId) { 387 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 388 sp<hardware::camera2::ICameraDeviceUser> device; 389 { 390 SCOPED_TRACE("openNewDevice"); 391 binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"), 392 hardware::ICameraService::USE_CALLING_UID, /*out*/&device); 393 EXPECT_TRUE(res.isOk()) << res; 394 } 395 auto p = std::make_pair(callbacks, device); 396 openDeviceList.push_back(p); 397 return p; 398 } 399 400 void closeDevice(std::pair<sp<TestCameraDeviceCallbacks>, 401 sp<hardware::camera2::ICameraDeviceUser>>& p) { 402 if (p.second.get() != nullptr) { 403 binder::Status res = p.second->disconnect(); 404 EXPECT_TRUE(res.isOk()) << res; 405 { 406 SCOPED_TRACE("closeDevice"); 407 EXPECT_FALSE(p.first->hadError()); 408 } 409 } 410 auto iter = std::find(openDeviceList.begin(), openDeviceList.end(), p); 411 if (iter != openDeviceList.end()) { 412 openDeviceList.erase(iter); 413 } 414 } 415 416 virtual void SetUp() { 417 ProcessState::self()->startThreadPool(); 418 sp<IServiceManager> sm = defaultServiceManager(); 419 sp<IBinder> binder = sm->getService(String16("media.camera")); 420 service = interface_cast<hardware::ICameraService>(binder); 421 serviceListener = new TestCameraServiceListener(); 422 std::vector<hardware::CameraStatus> statuses; 423 service->addListener(serviceListener, &statuses); 424 service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, 425 &numCameras); 426 } 427 428 virtual void TearDown() { 429 service = nullptr; 430 numCameras = 0; 431 for (auto& p : openDeviceList) { 432 closeDevice(p); 433 } 434 } 435 436}; 437 438TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { 439 ASSERT_NOT_NULL(service); 440 EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras)); 441 for (int32_t i = 0; i < numCameras; i++) { 442 // Make sure we're available, or skip device tests otherwise 443 String16 cameraId(String8::format("%d",i)); 444 int32_t s = serviceListener->getStatus(cameraId); 445 EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s); 446 if (s != hardware::ICameraServiceListener::STATUS_PRESENT) { 447 continue; 448 } 449 binder::Status res; 450 auto p = openNewDevice(cameraId); 451 sp<TestCameraDeviceCallbacks> callbacks = p.first; 452 sp<hardware::camera2::ICameraDeviceUser> device = p.second; 453 454 // Setup a buffer queue; I'm just using the vendor opaque format here as that is 455 // guaranteed to be present 456 sp<IGraphicBufferProducer> gbProducer; 457 sp<IGraphicBufferConsumer> gbConsumer; 458 BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 459 sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer, 460 GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/2, /*controlledByApp*/true); 461 EXPECT_TRUE(opaqueConsumer.get() != nullptr); 462 opaqueConsumer->setName(String8("nom nom nom")); 463 464 // Set to VGA dimens for default, as that is guaranteed to be present 465 EXPECT_EQ(OK, gbConsumer->setDefaultBufferSize(640, 480)); 466 EXPECT_EQ(OK, gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)); 467 468 sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false)); 469 470 OutputConfiguration output(gbProducer, /*rotation*/0); 471 472 // Can we configure? 473 res = device->beginConfigure(); 474 EXPECT_TRUE(res.isOk()) << res; 475 status_t streamId; 476 res = device->createStream(output, &streamId); 477 EXPECT_TRUE(res.isOk()) << res; 478 EXPECT_LE(0, streamId); 479 res = device->endConfigure(/*isConstrainedHighSpeed*/ false); 480 EXPECT_TRUE(res.isOk()) << res; 481 EXPECT_FALSE(callbacks->hadError()); 482 483 // Can we make requests? 484 CameraMetadata requestTemplate; 485 res = device->createDefaultRequest(/*preview template*/1, 486 /*out*/&requestTemplate); 487 EXPECT_TRUE(res.isOk()) << res; 488 489 hardware::camera2::CaptureRequest request; 490 request.mMetadata = requestTemplate; 491 request.mSurfaceList.add(surface); 492 request.mIsReprocess = false; 493 int64_t lastFrameNumber = 0; 494 int64_t lastFrameNumberPrev = 0; 495 callbacks->clearStatus(); 496 497 hardware::camera2::utils::SubmitInfo info; 498 res = device->submitRequest(request, /*streaming*/true, /*out*/&info); 499 EXPECT_TRUE(res.isOk()) << res; 500 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 501 EXPECT_LE(0, info.mRequestId); 502 503 // Can we stop requests? 504 res = device->cancelRequest(info.mRequestId, /*out*/&lastFrameNumber); 505 EXPECT_TRUE(res.isOk()) << res; 506 EXPECT_TRUE(callbacks->waitForIdle()); 507 EXPECT_FALSE(callbacks->hadError()); 508 509 // Can we do it again? 510 lastFrameNumberPrev = info.mLastFrameNumber; 511 lastFrameNumber = 0; 512 requestTemplate.clear(); 513 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 514 /*out*/&requestTemplate); 515 EXPECT_TRUE(res.isOk()) << res; 516 hardware::camera2::CaptureRequest request2; 517 request2.mMetadata = requestTemplate; 518 request2.mSurfaceList.add(surface); 519 request2.mIsReprocess = false; 520 callbacks->clearStatus(); 521 hardware::camera2::utils::SubmitInfo info2; 522 res = device->submitRequest(request2, /*streaming*/true, 523 /*out*/&info2); 524 EXPECT_TRUE(res.isOk()) << res; 525 EXPECT_EQ(hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES, 526 info2.mLastFrameNumber); 527 lastFrameNumber = 0; 528 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 529 EXPECT_LE(0, info2.mRequestId); 530 res = device->cancelRequest(info2.mRequestId, /*out*/&lastFrameNumber); 531 EXPECT_TRUE(res.isOk()) << res; 532 EXPECT_TRUE(callbacks->waitForIdle()); 533 EXPECT_LE(lastFrameNumberPrev, lastFrameNumber); 534 sleep(/*second*/1); // allow some time for errors to show up, if any 535 EXPECT_FALSE(callbacks->hadError()); 536 537 // Can we do it with a request list? 538 lastFrameNumberPrev = lastFrameNumber; 539 lastFrameNumber = 0; 540 requestTemplate.clear(); 541 CameraMetadata requestTemplate2; 542 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 543 /*out*/&requestTemplate); 544 EXPECT_TRUE(res.isOk()) << res; 545 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 546 /*out*/&requestTemplate2); 547 EXPECT_TRUE(res.isOk()) << res; 548 android::hardware::camera2::CaptureRequest request3; 549 android::hardware::camera2::CaptureRequest request4; 550 request3.mMetadata = requestTemplate; 551 request3.mSurfaceList.add(surface); 552 request3.mIsReprocess = false; 553 request4.mMetadata = requestTemplate2; 554 request4.mSurfaceList.add(surface); 555 request4.mIsReprocess = false; 556 std::vector<hardware::camera2::CaptureRequest> requestList; 557 requestList.push_back(request3); 558 requestList.push_back(request4); 559 560 callbacks->clearStatus(); 561 hardware::camera2::utils::SubmitInfo info3; 562 res = device->submitRequestList(requestList, /*streaming*/false, 563 /*out*/&info3); 564 EXPECT_TRUE(res.isOk()) << res; 565 EXPECT_LE(0, info3.mRequestId); 566 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 567 EXPECT_TRUE(callbacks->waitForIdle()); 568 EXPECT_LE(lastFrameNumberPrev, info3.mLastFrameNumber); 569 sleep(/*second*/1); // allow some time for errors to show up, if any 570 EXPECT_FALSE(callbacks->hadError()); 571 572 // Can we unconfigure? 573 res = device->beginConfigure(); 574 EXPECT_TRUE(res.isOk()) << res; 575 res = device->deleteStream(streamId); 576 EXPECT_TRUE(res.isOk()) << res; 577 res = device->endConfigure(/*isConstrainedHighSpeed*/ false); 578 EXPECT_TRUE(res.isOk()) << res; 579 580 sleep(/*second*/1); // allow some time for errors to show up, if any 581 EXPECT_FALSE(callbacks->hadError()); 582 583 closeDevice(p); 584 } 585 586}; 587