CameraBinderTests.cpp revision d309fb9c8a2c4564d88fffba19c4e3688e4b862b
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 246// Exercise basic binder calls for the camera service 247TEST(CameraServiceBinderTest, CheckBinderCameraService) { 248 ProcessState::self()->startThreadPool(); 249 sp<IServiceManager> sm = defaultServiceManager(); 250 sp<IBinder> binder = sm->getService(String16("media.camera")); 251 ASSERT_NOT_NULL(binder); 252 sp<ICameraService> service = interface_cast<ICameraService>(binder); 253 254 255 int32_t numCameras = service->getNumberOfCameras(); 256 EXPECT_LE(0, numCameras); 257 258 // Check listener binder calls 259 sp<TestCameraServiceListener> listener(new TestCameraServiceListener()); 260 EXPECT_EQ(OK, service->addListener(listener)); 261 262 EXPECT_TRUE(listener->waitForNumCameras(numCameras)); 263 264 for (int32_t i = 0; i < numCameras; i++) { 265 // We only care about binder calls for the Camera2 API. Camera1 is deprecated. 266 status_t camera2Support = service->supportsCameraApi(i, ICameraService::API_VERSION_2); 267 if (camera2Support != OK) { 268 EXPECT_EQ(-EOPNOTSUPP, camera2Support); 269 continue; 270 } 271 272 // Check metadata binder call 273 CameraMetadata metadata; 274 EXPECT_EQ(OK, service->getCameraCharacteristics(i, &metadata)); 275 EXPECT_FALSE(metadata.isEmpty()); 276 277 // Make sure we're available, or skip device tests otherwise 278 ICameraServiceListener::Status s = listener->getStatus(i); 279 EXPECT_EQ(ICameraServiceListener::STATUS_AVAILABLE, s); 280 if (s != ICameraServiceListener::STATUS_AVAILABLE) { 281 continue; 282 } 283 284 // Check connect binder calls 285 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 286 sp<ICameraDeviceUser> device; 287 EXPECT_EQ(OK, service->connectDevice(callbacks, i, String16("meeeeeeeee!"), 288 ICameraService::USE_CALLING_UID, /*out*/device)); 289 ASSERT_NE(nullptr, device.get()); 290 device->disconnect(); 291 EXPECT_FALSE(callbacks->hadError()); 292 293 ICameraServiceListener::TorchStatus torchStatus = listener->getTorchStatus(i); 294 if (torchStatus == ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) { 295 // Check torch calls 296 EXPECT_EQ(OK, service->setTorchMode(String16(String8::format("%d", i)), 297 /*enabled*/true, callbacks)); 298 EXPECT_TRUE(listener->waitForTorchState( 299 ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i)); 300 EXPECT_EQ(OK, service->setTorchMode(String16(String8::format("%d", i)), 301 /*enabled*/false, callbacks)); 302 EXPECT_TRUE(listener->waitForTorchState( 303 ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i)); 304 } 305 } 306 307 EXPECT_EQ(OK, service->removeListener(listener)); 308} 309 310// Test fixture for client focused binder tests 311class CameraClientBinderTest : public testing::Test { 312protected: 313 sp<ICameraService> service; 314 int32_t numCameras; 315 std::vector<std::pair<sp<TestCameraDeviceCallbacks>, sp<ICameraDeviceUser>>> openDeviceList; 316 sp<TestCameraServiceListener> serviceListener; 317 318 std::pair<sp<TestCameraDeviceCallbacks>, sp<ICameraDeviceUser>> openNewDevice(int deviceId) { 319 320 sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks()); 321 sp<ICameraDeviceUser> device; 322 { 323 SCOPED_TRACE("openNewDevice"); 324 EXPECT_EQ(OK, service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"), 325 ICameraService::USE_CALLING_UID, /*out*/device)); 326 } 327 auto p = std::make_pair(callbacks, device); 328 openDeviceList.push_back(p); 329 return p; 330 } 331 332 void closeDevice(std::pair<sp<TestCameraDeviceCallbacks>, sp<ICameraDeviceUser>>& p) { 333 if (p.second.get() != nullptr) { 334 p.second->disconnect(); 335 { 336 SCOPED_TRACE("closeDevice"); 337 EXPECT_FALSE(p.first->hadError()); 338 } 339 } 340 auto iter = std::find(openDeviceList.begin(), openDeviceList.end(), p); 341 if (iter != openDeviceList.end()) { 342 openDeviceList.erase(iter); 343 } 344 } 345 346 virtual void SetUp() { 347 ProcessState::self()->startThreadPool(); 348 sp<IServiceManager> sm = defaultServiceManager(); 349 sp<IBinder> binder = sm->getService(String16("media.camera")); 350 service = interface_cast<ICameraService>(binder); 351 serviceListener = new TestCameraServiceListener(); 352 service->addListener(serviceListener); 353 numCameras = service->getNumberOfCameras(); 354 } 355 356 virtual void TearDown() { 357 service = nullptr; 358 numCameras = 0; 359 for (auto& p : openDeviceList) { 360 closeDevice(p); 361 } 362 } 363 364}; 365 366TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { 367 ASSERT_NOT_NULL(service); 368 369 EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras)); 370 for (int32_t i = 0; i < numCameras; i++) { 371 // Make sure we're available, or skip device tests otherwise 372 ICameraServiceListener::Status s = serviceListener->getStatus(i); 373 EXPECT_EQ(ICameraServiceListener::STATUS_AVAILABLE, s); 374 if (s != ICameraServiceListener::STATUS_AVAILABLE) { 375 continue; 376 } 377 378 auto p = openNewDevice(i); 379 sp<TestCameraDeviceCallbacks> callbacks = p.first; 380 sp<ICameraDeviceUser> device = p.second; 381 382 // Setup a buffer queue; I'm just using the vendor opaque format here as that is 383 // guaranteed to be present 384 sp<IGraphicBufferProducer> gbProducer; 385 sp<IGraphicBufferConsumer> gbConsumer; 386 BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); 387 sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer, 388 GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/2, /*controlledByApp*/true); 389 EXPECT_TRUE(opaqueConsumer.get() != nullptr); 390 opaqueConsumer->setName(String8("nom nom nom")); 391 392 // Set to VGA dimens for default, as that is guaranteed to be present 393 EXPECT_EQ(OK, gbConsumer->setDefaultBufferSize(640, 480)); 394 EXPECT_EQ(OK, gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)); 395 396 sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false)); 397 398 OutputConfiguration output(gbProducer, /*rotation*/0); 399 400 // Can we configure? 401 EXPECT_EQ(OK, device->beginConfigure()); 402 status_t streamId = device->createStream(output); 403 EXPECT_LE(0, streamId); 404 EXPECT_EQ(OK, device->endConfigure()); 405 EXPECT_FALSE(callbacks->hadError()); 406 407 // Can we make requests? 408 CameraMetadata requestTemplate; 409 EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1, 410 /*out*/&requestTemplate)); 411 sp<CaptureRequest> request(new CaptureRequest()); 412 request->mMetadata = requestTemplate; 413 request->mSurfaceList.add(surface); 414 request->mIsReprocess = false; 415 int64_t lastFrameNumber = 0; 416 int64_t lastFrameNumberPrev = 0; 417 callbacks->clearStatus(); 418 int requestId = device->submitRequest(request, /*streaming*/true, /*out*/&lastFrameNumber); 419 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 420 EXPECT_LE(0, requestId); 421 422 // Can we stop requests? 423 EXPECT_EQ(OK, device->cancelRequest(requestId, /*out*/&lastFrameNumber)); 424 EXPECT_TRUE(callbacks->waitForIdle()); 425 EXPECT_FALSE(callbacks->hadError()); 426 427 // Can we do it again? 428 lastFrameNumberPrev = lastFrameNumber; 429 lastFrameNumber = 0; 430 requestTemplate.clear(); 431 EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1, 432 /*out*/&requestTemplate)); 433 sp<CaptureRequest> request2(new CaptureRequest()); 434 request2->mMetadata = requestTemplate; 435 request2->mSurfaceList.add(surface); 436 request2->mIsReprocess = false; 437 callbacks->clearStatus(); 438 int requestId2 = device->submitRequest(request2, /*streaming*/true, 439 /*out*/&lastFrameNumber); 440 EXPECT_EQ(-1, lastFrameNumber); 441 lastFrameNumber = 0; 442 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 443 EXPECT_LE(0, requestId2); 444 EXPECT_EQ(OK, device->cancelRequest(requestId2, /*out*/&lastFrameNumber)); 445 EXPECT_TRUE(callbacks->waitForIdle()); 446 EXPECT_LE(lastFrameNumberPrev, lastFrameNumber); 447 sleep(/*second*/1); // allow some time for errors to show up, if any 448 EXPECT_FALSE(callbacks->hadError()); 449 450 // Can we do it with a request list? 451 lastFrameNumberPrev = lastFrameNumber; 452 lastFrameNumber = 0; 453 requestTemplate.clear(); 454 CameraMetadata requestTemplate2; 455 EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1, 456 /*out*/&requestTemplate)); 457 EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1, 458 /*out*/&requestTemplate2)); 459 sp<CaptureRequest> request3(new CaptureRequest()); 460 sp<CaptureRequest> request4(new CaptureRequest()); 461 request3->mMetadata = requestTemplate; 462 request3->mSurfaceList.add(surface); 463 request3->mIsReprocess = false; 464 request4->mMetadata = requestTemplate2; 465 request4->mSurfaceList.add(surface); 466 request4->mIsReprocess = false; 467 List<sp<CaptureRequest>> requestList; 468 requestList.push_back(request3); 469 requestList.push_back(request4); 470 471 callbacks->clearStatus(); 472 int requestId3 = device->submitRequestList(requestList, /*streaming*/false, 473 /*out*/&lastFrameNumber); 474 EXPECT_LE(0, requestId3); 475 EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT)); 476 EXPECT_TRUE(callbacks->waitForIdle()); 477 EXPECT_LE(lastFrameNumberPrev, lastFrameNumber); 478 sleep(/*second*/1); // allow some time for errors to show up, if any 479 EXPECT_FALSE(callbacks->hadError()); 480 481 // Can we unconfigure? 482 EXPECT_EQ(OK, device->beginConfigure()); 483 EXPECT_EQ(OK, device->deleteStream(streamId)); 484 EXPECT_EQ(OK, device->endConfigure()); 485 sleep(/*second*/1); // allow some time for errors to show up, if any 486 EXPECT_FALSE(callbacks->hadError()); 487 488 closeDevice(p); 489 } 490 491}; 492