CameraBinderTests.cpp revision f51fca277eb5b86bd0b2e3fc90ecb2b63089de29
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(int64_t lastFrameNumber) { 221 (void) lastFrameNumber; 222 Mutex::Autolock l(mLock); 223 mLastStatus = REPEATING_REQUEST_ERROR; 224 mStatusesHit.push_back(mLastStatus); 225 mStatusCondition.broadcast(); 226 return binder::Status::ok(); 227 } 228 229 virtual binder::Status onRequestQueueEmpty() { 230 Mutex::Autolock l(mLock); 231 mLastStatus = REQUEST_QUEUE_EMPTY; 232 mStatusesHit.push_back(mLastStatus); 233 mStatusCondition.broadcast(); 234 return binder::Status::ok(); 235 } 236 237 // Test helper functions: 238 239 bool hadError() const { 240 Mutex::Autolock l(mLock); 241 return mError; 242 } 243 244 bool waitForStatus(Status status) const { 245 Mutex::Autolock l(mLock); 246 if (mLastStatus == status) { 247 return true; 248 } 249 250 while (std::find(mStatusesHit.begin(), mStatusesHit.end(), status) 251 == mStatusesHit.end()) { 252 253 if (mStatusCondition.waitRelative(mLock, IDLE_TIMEOUT) != OK) { 254 mStatusesHit.clear(); 255 return false; 256 } 257 } 258 mStatusesHit.clear(); 259 260 return true; 261 262 } 263 264 void clearStatus() const { 265 Mutex::Autolock l(mLock); 266 mStatusesHit.clear(); 267 } 268 269 bool waitForIdle() const { 270 return waitForStatus(IDLE); 271 } 272 273}; 274 275namespace { 276 Mutex gLock; 277 class DeathNotifier : public IBinder::DeathRecipient 278 { 279 public: 280 DeathNotifier() {} 281 282 virtual void binderDied(const wp<IBinder>& /*who*/) { 283 ALOGV("binderDied"); 284 Mutex::Autolock _l(gLock); 285 ALOGW("Camera service died!"); 286 } 287 }; 288 sp<DeathNotifier> gDeathNotifier; 289}; // anonymous namespace 290 291// Exercise basic binder calls for the camera service 292TEST(CameraServiceBinderTest, CheckBinderCameraService) { 293 ProcessState::self()->startThreadPool(); 294 sp<IServiceManager> sm = defaultServiceManager(); 295 sp<IBinder> binder = sm->getService(String16("media.camera")); 296 ASSERT_NOT_NULL(binder); 297 if (gDeathNotifier == NULL) { 298 gDeathNotifier = new DeathNotifier(); 299 } 300 binder->linkToDeath(gDeathNotifier); 301 sp<hardware::ICameraService> service = 302 interface_cast<hardware::ICameraService>(binder); 303 304 binder::Status res; 305 306 int32_t numCameras = 0; 307 res = service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras); 308 EXPECT_TRUE(res.isOk()) << res; 309 EXPECT_LE(0, numCameras); 310 311 // Check listener binder calls 312 sp<TestCameraServiceListener> listener(new TestCameraServiceListener()); 313 std::vector<hardware::CameraStatus> statuses; 314 res = service->addListener(listener, &statuses); 315 EXPECT_TRUE(res.isOk()) << res; 316 317 EXPECT_EQ(numCameras, static_cast<const int>(statuses.size())); 318 319 for (int32_t i = 0; i < numCameras; i++) { 320 String16 cameraId = String16(String8::format("%d", i)); 321 bool isSupported = false; 322 res = service->supportsCameraApi(cameraId, 323 hardware::ICameraService::API_VERSION_2, &isSupported); 324 EXPECT_TRUE(res.isOk()) << res; 325 326 // We only care about binder calls for the Camera2 API. Camera1 is deprecated. 327 if (!isSupported) { 328 continue; 329 } 330 331 // Check metadata binder call 332 CameraMetadata metadata; 333 res = service->getCameraCharacteristics(cameraId, &metadata); 334 EXPECT_TRUE(res.isOk()) << res; 335 EXPECT_FALSE(metadata.isEmpty()); 336 337 // Make sure we're available, or skip device tests otherwise 338 int32_t s = listener->getStatus(cameraId); 339 EXPECT_EQ(::android::hardware::ICameraServiceListener::STATUS_PRESENT, s); 340 if (s != ::android::hardware::ICameraServiceListener::STATUS_PRESENT) { 341 continue; 342 } 343 344 // Check connect binder calls 345 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 346 sp<hardware::camera2::ICameraDeviceUser> device; 347 res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"), 348 hardware::ICameraService::USE_CALLING_UID, /*out*/&device); 349 EXPECT_TRUE(res.isOk()) << res; 350 ASSERT_NE(nullptr, device.get()); 351 device->disconnect(); 352 EXPECT_FALSE(callbacks->hadError()); 353 354 int32_t torchStatus = listener->getTorchStatus(i); 355 if (torchStatus == hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) { 356 // Check torch calls 357 res = service->setTorchMode(cameraId, 358 /*enabled*/true, callbacks); 359 EXPECT_TRUE(res.isOk()) << res; 360 EXPECT_TRUE(listener->waitForTorchState( 361 hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i)); 362 res = service->setTorchMode(cameraId, 363 /*enabled*/false, callbacks); 364 EXPECT_TRUE(res.isOk()) << res; 365 EXPECT_TRUE(listener->waitForTorchState( 366 hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i)); 367 } 368 } 369 370 res = service->removeListener(listener); 371 EXPECT_TRUE(res.isOk()) << res; 372} 373 374// Test fixture for client focused binder tests 375class CameraClientBinderTest : public testing::Test { 376protected: 377 sp<hardware::ICameraService> service; 378 int32_t numCameras; 379 std::vector<std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>> 380 openDeviceList; 381 sp<TestCameraServiceListener> serviceListener; 382 383 std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>> 384 openNewDevice(const String16& deviceId) { 385 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 386 sp<hardware::camera2::ICameraDeviceUser> device; 387 { 388 SCOPED_TRACE("openNewDevice"); 389 binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"), 390 hardware::ICameraService::USE_CALLING_UID, /*out*/&device); 391 EXPECT_TRUE(res.isOk()) << res; 392 } 393 auto p = std::make_pair(callbacks, device); 394 openDeviceList.push_back(p); 395 return p; 396 } 397 398 void closeDevice(std::pair<sp<TestCameraDeviceCallbacks>, 399 sp<hardware::camera2::ICameraDeviceUser>>& p) { 400 if (p.second.get() != nullptr) { 401 binder::Status res = p.second->disconnect(); 402 EXPECT_TRUE(res.isOk()) << res; 403 { 404 SCOPED_TRACE("closeDevice"); 405 EXPECT_FALSE(p.first->hadError()); 406 } 407 } 408 auto iter = std::find(openDeviceList.begin(), openDeviceList.end(), p); 409 if (iter != openDeviceList.end()) { 410 openDeviceList.erase(iter); 411 } 412 } 413 414 virtual void SetUp() { 415 ProcessState::self()->startThreadPool(); 416 sp<IServiceManager> sm = defaultServiceManager(); 417 sp<IBinder> binder = sm->getService(String16("media.camera")); 418 service = interface_cast<hardware::ICameraService>(binder); 419 serviceListener = new TestCameraServiceListener(); 420 std::vector<hardware::CameraStatus> statuses; 421 service->addListener(serviceListener, &statuses); 422 service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, 423 &numCameras); 424 } 425 426 virtual void TearDown() { 427 service = nullptr; 428 numCameras = 0; 429 for (auto& p : openDeviceList) { 430 closeDevice(p); 431 } 432 } 433 434}; 435 436TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { 437 ASSERT_NOT_NULL(service); 438 EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras)); 439 for (int32_t i = 0; i < numCameras; i++) { 440 // Make sure we're available, or skip device tests otherwise 441 String16 cameraId(String8::format("%d",i)); 442 int32_t s = serviceListener->getStatus(cameraId); 443 EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s); 444 if (s != hardware::ICameraServiceListener::STATUS_PRESENT) { 445 continue; 446 } 447 binder::Status res; 448 auto p = openNewDevice(cameraId); 449 sp<TestCameraDeviceCallbacks> callbacks = p.first; 450 sp<hardware::camera2::ICameraDeviceUser> device = p.second; 451 452 // Setup a buffer queue; I'm just using the vendor opaque format here as that is 453 // guaranteed to be present 454 sp<IGraphicBufferProducer> gbProducer; 455 sp<IGraphicBufferConsumer> gbConsumer; 456 BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 457 sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer, 458 GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/2, /*controlledByApp*/true); 459 EXPECT_TRUE(opaqueConsumer.get() != nullptr); 460 opaqueConsumer->setName(String8("nom nom nom")); 461 462 // Set to VGA dimens for default, as that is guaranteed to be present 463 EXPECT_EQ(OK, gbConsumer->setDefaultBufferSize(640, 480)); 464 EXPECT_EQ(OK, gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)); 465 466 sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false)); 467 468 OutputConfiguration output(gbProducer, /*rotation*/0); 469 470 // Can we configure? 471 res = device->beginConfigure(); 472 EXPECT_TRUE(res.isOk()) << res; 473 status_t streamId; 474 res = device->createStream(output, &streamId); 475 EXPECT_TRUE(res.isOk()) << res; 476 EXPECT_LE(0, streamId); 477 res = device->endConfigure(/*isConstrainedHighSpeed*/ false); 478 EXPECT_TRUE(res.isOk()) << res; 479 EXPECT_FALSE(callbacks->hadError()); 480 481 // Can we make requests? 482 CameraMetadata requestTemplate; 483 res = device->createDefaultRequest(/*preview template*/1, 484 /*out*/&requestTemplate); 485 EXPECT_TRUE(res.isOk()) << res; 486 487 hardware::camera2::CaptureRequest request; 488 request.mMetadata = requestTemplate; 489 request.mSurfaceList.add(surface); 490 request.mIsReprocess = false; 491 int64_t lastFrameNumber = 0; 492 int64_t lastFrameNumberPrev = 0; 493 callbacks->clearStatus(); 494 495 hardware::camera2::utils::SubmitInfo info; 496 res = device->submitRequest(request, /*streaming*/true, /*out*/&info); 497 EXPECT_TRUE(res.isOk()) << res; 498 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 499 EXPECT_LE(0, info.mRequestId); 500 501 // Can we stop requests? 502 res = device->cancelRequest(info.mRequestId, /*out*/&lastFrameNumber); 503 EXPECT_TRUE(res.isOk()) << res; 504 EXPECT_TRUE(callbacks->waitForIdle()); 505 EXPECT_FALSE(callbacks->hadError()); 506 507 // Can we do it again? 508 lastFrameNumberPrev = info.mLastFrameNumber; 509 lastFrameNumber = 0; 510 requestTemplate.clear(); 511 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 512 /*out*/&requestTemplate); 513 EXPECT_TRUE(res.isOk()) << res; 514 hardware::camera2::CaptureRequest request2; 515 request2.mMetadata = requestTemplate; 516 request2.mSurfaceList.add(surface); 517 request2.mIsReprocess = false; 518 callbacks->clearStatus(); 519 hardware::camera2::utils::SubmitInfo info2; 520 res = device->submitRequest(request2, /*streaming*/true, 521 /*out*/&info2); 522 EXPECT_TRUE(res.isOk()) << res; 523 EXPECT_EQ(hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES, 524 info2.mLastFrameNumber); 525 lastFrameNumber = 0; 526 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 527 EXPECT_LE(0, info2.mRequestId); 528 res = device->cancelRequest(info2.mRequestId, /*out*/&lastFrameNumber); 529 EXPECT_TRUE(res.isOk()) << res; 530 EXPECT_TRUE(callbacks->waitForIdle()); 531 EXPECT_LE(lastFrameNumberPrev, lastFrameNumber); 532 sleep(/*second*/1); // allow some time for errors to show up, if any 533 EXPECT_FALSE(callbacks->hadError()); 534 535 // Can we do it with a request list? 536 lastFrameNumberPrev = lastFrameNumber; 537 lastFrameNumber = 0; 538 requestTemplate.clear(); 539 CameraMetadata requestTemplate2; 540 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 541 /*out*/&requestTemplate); 542 EXPECT_TRUE(res.isOk()) << res; 543 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 544 /*out*/&requestTemplate2); 545 EXPECT_TRUE(res.isOk()) << res; 546 android::hardware::camera2::CaptureRequest request3; 547 android::hardware::camera2::CaptureRequest request4; 548 request3.mMetadata = requestTemplate; 549 request3.mSurfaceList.add(surface); 550 request3.mIsReprocess = false; 551 request4.mMetadata = requestTemplate2; 552 request4.mSurfaceList.add(surface); 553 request4.mIsReprocess = false; 554 std::vector<hardware::camera2::CaptureRequest> requestList; 555 requestList.push_back(request3); 556 requestList.push_back(request4); 557 558 callbacks->clearStatus(); 559 hardware::camera2::utils::SubmitInfo info3; 560 res = device->submitRequestList(requestList, /*streaming*/false, 561 /*out*/&info3); 562 EXPECT_TRUE(res.isOk()) << res; 563 EXPECT_LE(0, info3.mRequestId); 564 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 565 EXPECT_TRUE(callbacks->waitForIdle()); 566 EXPECT_LE(lastFrameNumberPrev, info3.mLastFrameNumber); 567 sleep(/*second*/1); // allow some time for errors to show up, if any 568 EXPECT_FALSE(callbacks->hadError()); 569 570 // Can we unconfigure? 571 res = device->beginConfigure(); 572 EXPECT_TRUE(res.isOk()) << res; 573 res = device->deleteStream(streamId); 574 EXPECT_TRUE(res.isOk()) << res; 575 res = device->endConfigure(/*isConstrainedHighSpeed*/ false); 576 EXPECT_TRUE(res.isOk()) << res; 577 578 sleep(/*second*/1); // allow some time for errors to show up, if any 579 EXPECT_FALSE(callbacks->hadError()); 580 581 closeDevice(p); 582 } 583 584}; 585