CameraBinderTests.cpp revision 9d06601e54848f076b7472a376c672215cd70c46
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<int32_t, 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, int32_t 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(int32_t 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 res = service->addListener(listener); 314 EXPECT_TRUE(res.isOk()) << res; 315 316 EXPECT_TRUE(listener->waitForNumCameras(numCameras)); 317 318 for (int32_t i = 0; i < numCameras; i++) { 319 bool isSupported = false; 320 res = service->supportsCameraApi(i, 321 hardware::ICameraService::API_VERSION_2, &isSupported); 322 EXPECT_TRUE(res.isOk()) << res; 323 324 // We only care about binder calls for the Camera2 API. Camera1 is deprecated. 325 if (!isSupported) { 326 continue; 327 } 328 329 // Check metadata binder call 330 CameraMetadata metadata; 331 res = service->getCameraCharacteristics(i, &metadata); 332 EXPECT_TRUE(res.isOk()) << res; 333 EXPECT_FALSE(metadata.isEmpty()); 334 335 // Make sure we're available, or skip device tests otherwise 336 int32_t s = listener->getStatus(i); 337 EXPECT_EQ(::android::hardware::ICameraServiceListener::STATUS_PRESENT, s); 338 if (s != ::android::hardware::ICameraServiceListener::STATUS_PRESENT) { 339 continue; 340 } 341 342 // Check connect binder calls 343 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 344 sp<hardware::camera2::ICameraDeviceUser> device; 345 res = service->connectDevice(callbacks, i, String16("meeeeeeeee!"), 346 hardware::ICameraService::USE_CALLING_UID, /*out*/&device); 347 EXPECT_TRUE(res.isOk()) << res; 348 ASSERT_NE(nullptr, device.get()); 349 device->disconnect(); 350 EXPECT_FALSE(callbacks->hadError()); 351 352 int32_t torchStatus = listener->getTorchStatus(i); 353 if (torchStatus == hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) { 354 // Check torch calls 355 res = service->setTorchMode(String16(String8::format("%d", i)), 356 /*enabled*/true, callbacks); 357 EXPECT_TRUE(res.isOk()) << res; 358 EXPECT_TRUE(listener->waitForTorchState( 359 hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i)); 360 res = service->setTorchMode(String16(String8::format("%d", i)), 361 /*enabled*/false, callbacks); 362 EXPECT_TRUE(res.isOk()) << res; 363 EXPECT_TRUE(listener->waitForTorchState( 364 hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i)); 365 } 366 } 367 368 res = service->removeListener(listener); 369 EXPECT_TRUE(res.isOk()) << res; 370} 371 372// Test fixture for client focused binder tests 373class CameraClientBinderTest : public testing::Test { 374protected: 375 sp<hardware::ICameraService> service; 376 int32_t numCameras; 377 std::vector<std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>>> 378 openDeviceList; 379 sp<TestCameraServiceListener> serviceListener; 380 381 std::pair<sp<TestCameraDeviceCallbacks>, sp<hardware::camera2::ICameraDeviceUser>> 382 openNewDevice(int deviceId) { 383 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 384 sp<hardware::camera2::ICameraDeviceUser> device; 385 { 386 SCOPED_TRACE("openNewDevice"); 387 binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"), 388 hardware::ICameraService::USE_CALLING_UID, /*out*/&device); 389 EXPECT_TRUE(res.isOk()) << res; 390 } 391 auto p = std::make_pair(callbacks, device); 392 openDeviceList.push_back(p); 393 return p; 394 } 395 396 void closeDevice(std::pair<sp<TestCameraDeviceCallbacks>, 397 sp<hardware::camera2::ICameraDeviceUser>>& p) { 398 if (p.second.get() != nullptr) { 399 binder::Status res = p.second->disconnect(); 400 EXPECT_TRUE(res.isOk()) << res; 401 { 402 SCOPED_TRACE("closeDevice"); 403 EXPECT_FALSE(p.first->hadError()); 404 } 405 } 406 auto iter = std::find(openDeviceList.begin(), openDeviceList.end(), p); 407 if (iter != openDeviceList.end()) { 408 openDeviceList.erase(iter); 409 } 410 } 411 412 virtual void SetUp() { 413 ProcessState::self()->startThreadPool(); 414 sp<IServiceManager> sm = defaultServiceManager(); 415 sp<IBinder> binder = sm->getService(String16("media.camera")); 416 service = interface_cast<hardware::ICameraService>(binder); 417 serviceListener = new TestCameraServiceListener(); 418 service->addListener(serviceListener); 419 service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, 420 &numCameras); 421 } 422 423 virtual void TearDown() { 424 service = nullptr; 425 numCameras = 0; 426 for (auto& p : openDeviceList) { 427 closeDevice(p); 428 } 429 } 430 431}; 432 433TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { 434 ASSERT_NOT_NULL(service); 435 EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras)); 436 for (int32_t i = 0; i < numCameras; i++) { 437 // Make sure we're available, or skip device tests otherwise 438 int32_t s = serviceListener->getStatus(i); 439 EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s); 440 if (s != hardware::ICameraServiceListener::STATUS_PRESENT) { 441 continue; 442 } 443 binder::Status res; 444 445 auto p = openNewDevice(i); 446 sp<TestCameraDeviceCallbacks> callbacks = p.first; 447 sp<hardware::camera2::ICameraDeviceUser> device = p.second; 448 449 // Setup a buffer queue; I'm just using the vendor opaque format here as that is 450 // guaranteed to be present 451 sp<IGraphicBufferProducer> gbProducer; 452 sp<IGraphicBufferConsumer> gbConsumer; 453 BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 454 sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer, 455 GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/2, /*controlledByApp*/true); 456 EXPECT_TRUE(opaqueConsumer.get() != nullptr); 457 opaqueConsumer->setName(String8("nom nom nom")); 458 459 // Set to VGA dimens for default, as that is guaranteed to be present 460 EXPECT_EQ(OK, gbConsumer->setDefaultBufferSize(640, 480)); 461 EXPECT_EQ(OK, gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)); 462 463 sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false)); 464 465 OutputConfiguration output(gbProducer, /*rotation*/0); 466 467 // Can we configure? 468 res = device->beginConfigure(); 469 EXPECT_TRUE(res.isOk()) << res; 470 status_t streamId; 471 res = device->createStream(output, &streamId); 472 EXPECT_TRUE(res.isOk()) << res; 473 EXPECT_LE(0, streamId); 474 res = device->endConfigure(/*isConstrainedHighSpeed*/ false); 475 EXPECT_TRUE(res.isOk()) << res; 476 EXPECT_FALSE(callbacks->hadError()); 477 478 // Can we make requests? 479 CameraMetadata requestTemplate; 480 res = device->createDefaultRequest(/*preview template*/1, 481 /*out*/&requestTemplate); 482 EXPECT_TRUE(res.isOk()) << res; 483 484 hardware::camera2::CaptureRequest request; 485 request.mMetadata = requestTemplate; 486 request.mSurfaceList.add(surface); 487 request.mIsReprocess = false; 488 int64_t lastFrameNumber = 0; 489 int64_t lastFrameNumberPrev = 0; 490 callbacks->clearStatus(); 491 492 hardware::camera2::utils::SubmitInfo info; 493 res = device->submitRequest(request, /*streaming*/true, /*out*/&info); 494 EXPECT_TRUE(res.isOk()) << res; 495 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 496 EXPECT_LE(0, info.mRequestId); 497 498 // Can we stop requests? 499 res = device->cancelRequest(info.mRequestId, /*out*/&lastFrameNumber); 500 EXPECT_TRUE(res.isOk()) << res; 501 EXPECT_TRUE(callbacks->waitForIdle()); 502 EXPECT_FALSE(callbacks->hadError()); 503 504 // Can we do it again? 505 lastFrameNumberPrev = info.mLastFrameNumber; 506 lastFrameNumber = 0; 507 requestTemplate.clear(); 508 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 509 /*out*/&requestTemplate); 510 EXPECT_TRUE(res.isOk()) << res; 511 hardware::camera2::CaptureRequest request2; 512 request2.mMetadata = requestTemplate; 513 request2.mSurfaceList.add(surface); 514 request2.mIsReprocess = false; 515 callbacks->clearStatus(); 516 hardware::camera2::utils::SubmitInfo info2; 517 res = device->submitRequest(request2, /*streaming*/true, 518 /*out*/&info2); 519 EXPECT_TRUE(res.isOk()) << res; 520 EXPECT_EQ(hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES, 521 info2.mLastFrameNumber); 522 lastFrameNumber = 0; 523 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 524 EXPECT_LE(0, info2.mRequestId); 525 res = device->cancelRequest(info2.mRequestId, /*out*/&lastFrameNumber); 526 EXPECT_TRUE(res.isOk()) << res; 527 EXPECT_TRUE(callbacks->waitForIdle()); 528 EXPECT_LE(lastFrameNumberPrev, lastFrameNumber); 529 sleep(/*second*/1); // allow some time for errors to show up, if any 530 EXPECT_FALSE(callbacks->hadError()); 531 532 // Can we do it with a request list? 533 lastFrameNumberPrev = lastFrameNumber; 534 lastFrameNumber = 0; 535 requestTemplate.clear(); 536 CameraMetadata requestTemplate2; 537 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 538 /*out*/&requestTemplate); 539 EXPECT_TRUE(res.isOk()) << res; 540 res = device->createDefaultRequest(hardware::camera2::ICameraDeviceUser::TEMPLATE_PREVIEW, 541 /*out*/&requestTemplate2); 542 EXPECT_TRUE(res.isOk()) << res; 543 android::hardware::camera2::CaptureRequest request3; 544 android::hardware::camera2::CaptureRequest request4; 545 request3.mMetadata = requestTemplate; 546 request3.mSurfaceList.add(surface); 547 request3.mIsReprocess = false; 548 request4.mMetadata = requestTemplate2; 549 request4.mSurfaceList.add(surface); 550 request4.mIsReprocess = false; 551 std::vector<hardware::camera2::CaptureRequest> requestList; 552 requestList.push_back(request3); 553 requestList.push_back(request4); 554 555 callbacks->clearStatus(); 556 hardware::camera2::utils::SubmitInfo info3; 557 res = device->submitRequestList(requestList, /*streaming*/false, 558 /*out*/&info3); 559 EXPECT_TRUE(res.isOk()) << res; 560 EXPECT_LE(0, info3.mRequestId); 561 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 562 EXPECT_TRUE(callbacks->waitForIdle()); 563 EXPECT_LE(lastFrameNumberPrev, info3.mLastFrameNumber); 564 sleep(/*second*/1); // allow some time for errors to show up, if any 565 EXPECT_FALSE(callbacks->hadError()); 566 567 // Can we unconfigure? 568 res = device->beginConfigure(); 569 EXPECT_TRUE(res.isOk()) << res; 570 res = device->deleteStream(streamId); 571 EXPECT_TRUE(res.isOk()) << res; 572 res = device->endConfigure(/*isConstrainedHighSpeed*/ false); 573 EXPECT_TRUE(res.isOk()) << res; 574 575 sleep(/*second*/1); // allow some time for errors to show up, if any 576 EXPECT_FALSE(callbacks->hadError()); 577 578 closeDevice(p); 579 } 580 581}; 582