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