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