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