VtsHalCameraProviderV2_4TargetTest.cpp revision 1af9528966cb2d18590e783274dc8ac96c658edb
1/* 2 * Copyright (C) 2016 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_TAG "camera_hidl_hal_test" 18 19#include <chrono> 20#include <mutex> 21#include <regex> 22#include <unordered_map> 23#include <condition_variable> 24 25#include <inttypes.h> 26 27#include <android/hardware/camera/device/1.0/ICameraDevice.h> 28#include <android/hardware/camera/device/3.2/ICameraDevice.h> 29#include <android/hardware/camera/provider/2.4/ICameraProvider.h> 30#include <android/hidl/manager/1.0/IServiceManager.h> 31#include <binder/MemoryHeapBase.h> 32#include <CameraMetadata.h> 33#include <CameraParameters.h> 34#include <fmq/MessageQueue.h> 35#include <grallocusage/GrallocUsageConversion.h> 36#include <gui/BufferItemConsumer.h> 37#include <gui/BufferQueue.h> 38#include <gui/Surface.h> 39#include <hardware/gralloc.h> 40#include <hardware/gralloc1.h> 41#include <system/camera.h> 42#include <system/camera_metadata.h> 43#include <ui/GraphicBuffer.h> 44 45#include <VtsHalHidlTargetTestBase.h> 46 47using ::android::hardware::Return; 48using ::android::hardware::Void; 49using ::android::hardware::hidl_handle; 50using ::android::hardware::hidl_string; 51using ::android::hardware::hidl_vec; 52using ::android::sp; 53using ::android::wp; 54using ::android::GraphicBuffer; 55using ::android::IGraphicBufferProducer; 56using ::android::IGraphicBufferConsumer; 57using ::android::BufferQueue; 58using ::android::BufferItemConsumer; 59using ::android::Surface; 60using ::android::CameraParameters; 61using ::android::hardware::graphics::common::V1_0::BufferUsage; 62using ::android::hardware::graphics::common::V1_0::PixelFormat; 63using ::android::hardware::camera::common::V1_0::Status; 64using ::android::hardware::camera::common::V1_0::CameraDeviceStatus; 65using ::android::hardware::camera::common::V1_0::TorchMode; 66using ::android::hardware::camera::common::V1_0::TorchModeStatus; 67using ::android::hardware::camera::provider::V2_4::ICameraProvider; 68using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; 69using ::android::hardware::camera::device::V3_2::ICameraDevice; 70using ::android::hardware::camera::device::V3_2::BufferCache; 71using ::android::hardware::camera::device::V3_2::CaptureRequest; 72using ::android::hardware::camera::device::V3_2::CaptureResult; 73using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback; 74using ::android::hardware::camera::device::V3_2::ICameraDeviceSession; 75using ::android::hardware::camera::device::V3_2::NotifyMsg; 76using ::android::hardware::camera::device::V3_2::RequestTemplate; 77using ::android::hardware::camera::device::V3_2::Stream; 78using ::android::hardware::camera::device::V3_2::StreamType; 79using ::android::hardware::camera::device::V3_2::StreamRotation; 80using ::android::hardware::camera::device::V3_2::StreamConfiguration; 81using ::android::hardware::camera::device::V3_2::StreamConfigurationMode; 82using ::android::hardware::camera::device::V3_2::CameraMetadata; 83using ::android::hardware::camera::device::V3_2::HalStreamConfiguration; 84using ::android::hardware::camera::device::V3_2::BufferStatus; 85using ::android::hardware::camera::device::V3_2::StreamBuffer; 86using ::android::hardware::camera::device::V3_2::MsgType; 87using ::android::hardware::camera::device::V3_2::ErrorMsg; 88using ::android::hardware::camera::device::V3_2::ErrorCode; 89using ::android::hardware::camera::device::V1_0::CameraFacing; 90using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg; 91using ::android::hardware::camera::device::V1_0::CommandType; 92using ::android::hardware::camera::device::V1_0::DataCallbackMsg; 93using ::android::hardware::camera::device::V1_0::CameraFrameMetadata; 94using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback; 95using ::android::hardware::camera::device::V1_0::FrameCallbackFlag; 96using ::android::hardware::camera::device::V1_0::HandleTimestampMessage; 97using ::android::hardware::MessageQueue; 98using ::android::hardware::kSynchronizedReadWrite; 99using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; 100using ::android::hidl::manager::V1_0::IServiceManager; 101 102const char kCameraPassthroughServiceName[] = "legacy/0"; 103const char *kProviderFQName = "android.hardware.camera.provider@2.4::ICameraProvider"; 104const uint32_t kMaxPreviewWidth = 1920; 105const uint32_t kMaxPreviewHeight = 1080; 106const uint32_t kMaxVideoWidth = 4096; 107const uint32_t kMaxVideoHeight = 2160; 108const int64_t kStreamBufferTimeoutSec = 3; 109const int64_t kAutoFocusTimeoutSec = 5; 110const int64_t kTorchTimeoutSec = 1; 111const int64_t kEmptyFlushTimeoutMSec = 200; 112const char kDumpOutput[] = "/dev/null"; 113 114struct AvailableStream { 115 int32_t width; 116 int32_t height; 117 int32_t format; 118}; 119 120struct AvailableZSLInputOutput { 121 int32_t inputFormat; 122 int32_t outputFormat; 123}; 124 125namespace { 126 // "device@<version>/legacy/<id>" 127 const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)"; 128 const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302; 129 const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100; 130 const char *kHAL3_2 = "3.2"; 131 const char *kHAL1_0 = "1.0"; 132 133 bool matchDeviceName(const hidl_string& deviceName, 134 const hidl_string &providerType, std::smatch& sm) { 135 ::android::String8 pattern; 136 pattern.appendFormat(kDeviceNameRE, providerType.c_str()); 137 std::regex e(pattern.string()); 138 std::string deviceNameStd(deviceName.c_str()); 139 return std::regex_match(deviceNameStd, sm, e); 140 } 141 142 int getCameraDeviceVersion(const hidl_string& deviceName, 143 const hidl_string &providerType) { 144 std::smatch sm; 145 bool match = matchDeviceName(deviceName, providerType, sm); 146 if (!match) { 147 return -1; 148 } 149 std::string version = sm[1].str(); 150 if (version.compare(kHAL3_2) == 0) { 151 // maybe switched to 3.4 or define the hidl version enumlater 152 return CAMERA_DEVICE_API_VERSION_3_2; 153 } else if (version.compare(kHAL1_0) == 0) { 154 return CAMERA_DEVICE_API_VERSION_1_0; 155 } 156 return 0; 157 } 158 159 bool parseProviderName(const std::string& name, std::string *type /*out*/, 160 uint32_t *id /*out*/) { 161 if (!type || !id) { 162 ADD_FAILURE(); 163 return false; 164 } 165 166 std::string::size_type slashIdx = name.find('/'); 167 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) { 168 ADD_FAILURE() << "Provider name does not have / separator between type" 169 "and id"; 170 return false; 171 } 172 173 std::string typeVal = name.substr(0, slashIdx); 174 175 char *endPtr; 176 errno = 0; 177 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10); 178 if (errno != 0) { 179 ADD_FAILURE() << "cannot parse provider id as an integer:" << 180 name.c_str() << strerror(errno) << errno; 181 return false; 182 } 183 if (endPtr != name.c_str() + name.size()) { 184 ADD_FAILURE() << "provider id has unexpected length " << name.c_str(); 185 return false; 186 } 187 if (idVal < 0) { 188 ADD_FAILURE() << "id is negative: " << name.c_str() << idVal; 189 return false; 190 } 191 192 *type = typeVal; 193 *id = static_cast<uint32_t>(idVal); 194 195 return true; 196 } 197 198 Status mapToStatus(::android::status_t s) { 199 switch(s) { 200 case ::android::OK: 201 return Status::OK ; 202 case ::android::BAD_VALUE: 203 return Status::ILLEGAL_ARGUMENT ; 204 case -EBUSY: 205 return Status::CAMERA_IN_USE; 206 case -EUSERS: 207 return Status::MAX_CAMERAS_IN_USE; 208 case ::android::UNKNOWN_TRANSACTION: 209 return Status::METHOD_NOT_SUPPORTED; 210 case ::android::INVALID_OPERATION: 211 return Status::OPERATION_NOT_SUPPORTED; 212 case ::android::DEAD_OBJECT: 213 return Status::CAMERA_DISCONNECTED; 214 } 215 ALOGW("Unexpected HAL status code %d", s); 216 return Status::OPERATION_NOT_SUPPORTED; 217 } 218} 219 220// Test environment for camera 221class CameraHidlEnvironment : public ::testing::Environment { 222public: 223 // get the test environment singleton 224 static CameraHidlEnvironment* Instance() { 225 static CameraHidlEnvironment* instance = new CameraHidlEnvironment; 226 return instance; 227 } 228 229 virtual void SetUp() override; 230 virtual void TearDown() override; 231 232 std::unordered_map<std::string, sp<ICameraProvider> > mProviders; 233 234private: 235 CameraHidlEnvironment() {} 236 237 GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment); 238}; 239 240void CameraHidlEnvironment::SetUp() { 241 sp<IServiceManager> manager = IServiceManager::getService(); 242 ASSERT_NE(manager, nullptr); 243 244 manager->listByInterface(kProviderFQName, 245 [this](const hidl_vec<hidl_string> ®istered) { 246 std::string name; 247 uint32_t id; 248 sp<ICameraProvider> provider = nullptr; 249 for (size_t i = 0; i < registered.size(); i++) { 250 ASSERT_TRUE(parseProviderName(registered[i], 251 &name /*out*/, &id /*out*/)); 252 provider = ICameraProvider::tryGetService(registered[i]); 253 ALOGI_IF(provider, "provider is not nullptr, %p", provider.get()); 254 if (nullptr != provider.get()) { 255 mProviders.emplace(name, provider); 256 } 257 } 258 }); 259 260 261 std::string legacyName; 262 uint32_t legacyId; 263 ASSERT_TRUE(parseProviderName(kCameraPassthroughServiceName, 264 &legacyName /*out*/, &legacyId /*out*/)); 265 auto legacyIt = mProviders.find(legacyName); 266 //Add any legacy passthrough implementations 267 if (legacyIt == mProviders.end()) { 268 sp<ICameraProvider> provider = ICameraProvider::tryGetService( 269 kCameraPassthroughServiceName); 270 if (nullptr != provider.get()) { 271 mProviders.emplace(legacyName, provider); 272 } 273 } 274 275 ASSERT_FALSE(mProviders.empty()); 276} 277 278void CameraHidlEnvironment::TearDown() { 279 ALOGI("TearDown CameraHidlEnvironment"); 280} 281 282struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener { 283 BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {} 284 285 void onFrameAvailable(const android::BufferItem&) override { 286 sp<BufferItemConsumer> consumer = mConsumer.promote(); 287 ASSERT_NE(nullptr, consumer.get()); 288 289 android::BufferItem buffer; 290 ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0)); 291 ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer)); 292 } 293 294 private: 295 wp<BufferItemConsumer> mConsumer; 296}; 297 298struct PreviewWindowCb : public ICameraDevicePreviewCallback { 299 PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0), 300 mPreviewHeight(0), mFormat(0), mPreviewUsage(0), 301 mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {} 302 303 using dequeueBuffer_cb = 304 std::function<void(Status status, uint64_t bufferId, 305 const hidl_handle& buffer, uint32_t stride)>; 306 Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override; 307 308 Return<Status> enqueueBuffer(uint64_t bufferId) override; 309 310 Return<Status> cancelBuffer(uint64_t bufferId) override; 311 312 Return<Status> setBufferCount(uint32_t count) override; 313 314 Return<Status> setBuffersGeometry(uint32_t w, 315 uint32_t h, PixelFormat format) override; 316 317 Return<Status> setCrop(int32_t left, int32_t top, 318 int32_t right, int32_t bottom) override; 319 320 Return<Status> setUsage(BufferUsage usage) override; 321 322 Return<Status> setSwapInterval(int32_t interval) override; 323 324 using getMinUndequeuedBufferCount_cb = 325 std::function<void(Status status, uint32_t count)>; 326 Return<void> getMinUndequeuedBufferCount( 327 getMinUndequeuedBufferCount_cb _hidl_cb) override; 328 329 Return<Status> setTimestamp(int64_t timestamp) override; 330 331 private: 332 struct BufferHasher { 333 size_t operator()(const buffer_handle_t& buf) const { 334 if (buf == nullptr) 335 return 0; 336 337 size_t result = 1; 338 result = 31 * result + buf->numFds; 339 for (int i = 0; i < buf->numFds; i++) { 340 result = 31 * result + buf->data[i]; 341 } 342 return result; 343 } 344 }; 345 346 struct BufferComparator { 347 bool operator()(const buffer_handle_t& buf1, 348 const buffer_handle_t& buf2) const { 349 if (buf1->numFds == buf2->numFds) { 350 for (int i = 0; i < buf1->numFds; i++) { 351 if (buf1->data[i] != buf2->data[i]) { 352 return false; 353 } 354 } 355 return true; 356 } 357 return false; 358 } 359 }; 360 361 std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb); 362 void cleanupCirculatingBuffers(); 363 364 std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId 365 typedef std::unordered_map<const buffer_handle_t, uint64_t, 366 BufferHasher, BufferComparator> BufferIdMap; 367 368 BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map 369 std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap; 370 uint64_t mNextBufferId = 1; 371 372 uint32_t mPreviewWidth, mPreviewHeight; 373 int mFormat, mPreviewUsage; 374 int32_t mPreviewSwapInterval; 375 android_native_rect_t mCrop; 376 sp<ANativeWindow> mAnw; //Native window reference 377}; 378 379std::pair<bool, uint64_t> PreviewWindowCb::getBufferId( 380 ANativeWindowBuffer* anb) { 381 std::lock_guard<std::mutex> lock(mBufferIdMapLock); 382 383 buffer_handle_t& buf = anb->handle; 384 auto it = mBufferIdMap.find(buf); 385 if (it == mBufferIdMap.end()) { 386 uint64_t bufId = mNextBufferId++; 387 mBufferIdMap[buf] = bufId; 388 mReversedBufMap[bufId] = anb; 389 return std::make_pair(true, bufId); 390 } else { 391 return std::make_pair(false, it->second); 392 } 393} 394 395void PreviewWindowCb::cleanupCirculatingBuffers() { 396 std::lock_guard<std::mutex> lock(mBufferIdMapLock); 397 mBufferIdMap.clear(); 398 mReversedBufMap.clear(); 399} 400 401Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) { 402 ANativeWindowBuffer* anb; 403 auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb); 404 uint64_t bufferId = 0; 405 uint32_t stride = 0; 406 hidl_handle buf = nullptr; 407 if (rc == ::android::OK) { 408 auto pair = getBufferId(anb); 409 buf = (pair.first) ? anb->handle : nullptr; 410 bufferId = pair.second; 411 stride = anb->stride; 412 } 413 414 _hidl_cb(mapToStatus(rc), bufferId, buf, stride); 415 return Void(); 416} 417 418Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) { 419 if (mReversedBufMap.count(bufferId) == 0) { 420 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId); 421 return Status::ILLEGAL_ARGUMENT; 422 } 423 return mapToStatus(mAnw->queueBuffer(mAnw.get(), 424 mReversedBufMap.at(bufferId), -1)); 425} 426 427Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) { 428 if (mReversedBufMap.count(bufferId) == 0) { 429 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId); 430 return Status::ILLEGAL_ARGUMENT; 431 } 432 return mapToStatus(mAnw->cancelBuffer(mAnw.get(), 433 mReversedBufMap.at(bufferId), -1)); 434} 435 436Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) { 437 if (mAnw.get() != nullptr) { 438 // WAR for b/27039775 439 native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); 440 native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); 441 if (mPreviewWidth != 0) { 442 native_window_set_buffers_dimensions(mAnw.get(), 443 mPreviewWidth, mPreviewHeight); 444 native_window_set_buffers_format(mAnw.get(), mFormat); 445 } 446 if (mPreviewUsage != 0) { 447 native_window_set_usage(mAnw.get(), mPreviewUsage); 448 } 449 if (mPreviewSwapInterval >= 0) { 450 mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval); 451 } 452 if (mCrop.left >= 0) { 453 native_window_set_crop(mAnw.get(), &(mCrop)); 454 } 455 } 456 457 auto rc = native_window_set_buffer_count(mAnw.get(), count); 458 if (rc == ::android::OK) { 459 cleanupCirculatingBuffers(); 460 } 461 462 return mapToStatus(rc); 463} 464 465Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h, 466 PixelFormat format) { 467 auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h); 468 if (rc == ::android::OK) { 469 mPreviewWidth = w; 470 mPreviewHeight = h; 471 rc = native_window_set_buffers_format(mAnw.get(), 472 static_cast<int>(format)); 473 if (rc == ::android::OK) { 474 mFormat = static_cast<int>(format); 475 } 476 } 477 478 return mapToStatus(rc); 479} 480 481Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top, 482 int32_t right, int32_t bottom) { 483 android_native_rect_t crop = { left, top, right, bottom }; 484 auto rc = native_window_set_crop(mAnw.get(), &crop); 485 if (rc == ::android::OK) { 486 mCrop = crop; 487 } 488 return mapToStatus(rc); 489} 490 491Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) { 492 auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage)); 493 if (rc == ::android::OK) { 494 mPreviewUsage = static_cast<int>(usage); 495 } 496 return mapToStatus(rc); 497} 498 499Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) { 500 auto rc = mAnw->setSwapInterval(mAnw.get(), interval); 501 if (rc == ::android::OK) { 502 mPreviewSwapInterval = interval; 503 } 504 return mapToStatus(rc); 505} 506 507Return<void> PreviewWindowCb::getMinUndequeuedBufferCount( 508 getMinUndequeuedBufferCount_cb _hidl_cb) { 509 int count = 0; 510 auto rc = mAnw->query(mAnw.get(), 511 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count); 512 _hidl_cb(mapToStatus(rc), count); 513 return Void(); 514} 515 516Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) { 517 return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(), 518 timestamp)); 519} 520 521// The main test class for camera HIDL HAL. 522class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase { 523public: 524 virtual void SetUp() override {} 525 virtual void TearDown() override {} 526 527 hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider); 528 529 struct EmptyDeviceCb : public ICameraDeviceCallback { 530 virtual Return<void> processCaptureResult(const hidl_vec<CaptureResult>& /*results*/) override { 531 ALOGI("processCaptureResult callback"); 532 ADD_FAILURE(); // Empty callback should not reach here 533 return Void(); 534 } 535 536 virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override { 537 ALOGI("notify callback"); 538 ADD_FAILURE(); // Empty callback should not reach here 539 return Void(); 540 } 541 }; 542 543 struct DeviceCb : public ICameraDeviceCallback { 544 DeviceCb(CameraHidlTest *parent) : mParent(parent) {} 545 Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override; 546 Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override; 547 548 private: 549 CameraHidlTest *mParent; // Parent object 550 }; 551 552 struct TorchProviderCb : public ICameraProviderCallback { 553 TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {} 554 virtual Return<void> cameraDeviceStatusChange( 555 const hidl_string&, CameraDeviceStatus) override { 556 return Void(); 557 } 558 559 virtual Return<void> torchModeStatusChange( 560 const hidl_string&, TorchModeStatus newStatus) override { 561 std::lock_guard<std::mutex> l(mParent->mTorchLock); 562 mParent->mTorchStatus = newStatus; 563 mParent->mTorchCond.notify_one(); 564 return Void(); 565 } 566 567 private: 568 CameraHidlTest *mParent; // Parent object 569 }; 570 571 struct Camera1DeviceCb : 572 public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback { 573 Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {} 574 575 Return<void> notifyCallback(NotifyCallbackMsg msgType, 576 int32_t ext1, int32_t ext2) override; 577 578 Return<uint32_t> registerMemory(const hidl_handle& descriptor, 579 uint32_t bufferSize, uint32_t bufferCount) override; 580 581 Return<void> unregisterMemory(uint32_t memId) override; 582 583 Return<void> dataCallback(DataCallbackMsg msgType, 584 uint32_t data, uint32_t bufferIndex, 585 const CameraFrameMetadata& metadata) override; 586 587 Return<void> dataCallbackTimestamp(DataCallbackMsg msgType, 588 uint32_t data, uint32_t bufferIndex, 589 int64_t timestamp) override; 590 591 Return<void> handleCallbackTimestamp(DataCallbackMsg msgType, 592 const hidl_handle& frameData,uint32_t data, 593 uint32_t bufferIndex, int64_t timestamp) override; 594 595 Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType, 596 const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override; 597 598 599 private: 600 CameraHidlTest *mParent; // Parent object 601 }; 602 603 void openCameraDevice(const std::string &name, sp<ICameraProvider> provider, 604 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/); 605 void setupPreviewWindow( 606 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 607 sp<BufferItemConsumer> *bufferItemConsumer /*out*/, 608 sp<BufferItemHander> *bufferHandler /*out*/); 609 void stopPreviewAndClose( 610 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 611 void startPreview( 612 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 613 void enableMsgType(unsigned int msgType, 614 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 615 void disableMsgType(unsigned int msgType, 616 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 617 void getParameters( 618 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 619 CameraParameters *cameraParams /*out*/); 620 void setParameters( 621 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 622 const CameraParameters &cameraParams); 623 void waitForFrameLocked(DataCallbackMsg msgFrame, 624 std::unique_lock<std::mutex> &l); 625 void openEmptyDeviceSession(const std::string &name, 626 sp<ICameraProvider> provider, 627 sp<ICameraDeviceSession> *session /*out*/, 628 camera_metadata_t **staticMeta /*out*/); 629 void configurePreviewStream(const std::string &name, 630 sp<ICameraProvider> provider, 631 const AvailableStream *previewThreshold, 632 sp<ICameraDeviceSession> *session /*out*/, 633 Stream *previewStream /*out*/, 634 HalStreamConfiguration *halStreamConfig /*out*/, 635 bool *supportsPartialResults /*out*/, 636 uint32_t *partialResultCount /*out*/); 637 static Status getAvailableOutputStreams(camera_metadata_t *staticMeta, 638 std::vector<AvailableStream> &outputStreams, 639 const AvailableStream *threshold = nullptr); 640 static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); 641 static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, 642 AvailableStream &hfrStream); 643 static Status isZSLModeAvailable(camera_metadata_t *staticMeta); 644 static Status getZSLInputOutputMap(camera_metadata_t *staticMeta, 645 std::vector<AvailableZSLInputOutput> &inputOutputMap); 646 static Status findLargestSize( 647 const std::vector<AvailableStream> &streamSizes, 648 int32_t format, AvailableStream &result); 649 static Status isAutoFocusModeAvailable( 650 ::android::CameraParameters &cameraParams, const char *mode) ; 651 652protected: 653 654 // In-flight queue for tracking completion of capture requests. 655 struct InFlightRequest { 656 // Set by notify() SHUTTER call. 657 nsecs_t shutterTimestamp; 658 659 bool errorCodeValid; 660 ErrorCode errorCode; 661 662 //Is partial result supported 663 bool usePartialResult; 664 665 //Partial result count expected 666 uint32_t numPartialResults; 667 668 // Message queue 669 std::shared_ptr<ResultMetadataQueue> resultQueue; 670 671 // Set by process_capture_result call with valid metadata 672 bool haveResultMetadata; 673 674 // Decremented by calls to process_capture_result with valid output 675 // and input buffers 676 ssize_t numBuffersLeft; 677 678 // A 64bit integer to index the frame number associated with this result. 679 int64_t frameNumber; 680 681 // The partial result count (index) for this capture result. 682 int32_t partialResultCount; 683 684 // For buffer drop errors, the stream ID for the stream that lost a buffer. 685 // Otherwise -1. 686 int32_t errorStreamId; 687 688 // If this request has any input buffer 689 bool hasInputBuffer; 690 691 // Result metadata 692 ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult; 693 694 // Buffers are added by process_capture_result when output buffers 695 // return from HAL but framework. 696 ::android::Vector<StreamBuffer> resultOutputBuffers; 697 698 InFlightRequest(ssize_t numBuffers, bool hasInput, 699 bool partialResults, uint32_t partialCount, 700 std::shared_ptr<ResultMetadataQueue> queue = nullptr) : 701 shutterTimestamp(0), 702 errorCodeValid(false), 703 errorCode(ErrorCode::ERROR_BUFFER), 704 usePartialResult(partialResults), 705 numPartialResults(partialCount), 706 resultQueue(queue), 707 haveResultMetadata(false), 708 numBuffersLeft(numBuffers), 709 frameNumber(0), 710 partialResultCount(0), 711 errorStreamId(-1), 712 hasInputBuffer(hasInput) {} 713 }; 714 715 // Map from frame number to the in-flight request state 716 typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap; 717 718 std::mutex mLock; // Synchronize access to member variables 719 std::condition_variable mResultCondition; // Condition variable for incoming results 720 InFlightMap mInflightMap; // Map of all inflight requests 721 722 DataCallbackMsg mDataMessageTypeReceived; // Most recent message type received through data callbacks 723 uint32_t mVideoBufferIndex; // Buffer index of the most recent video buffer 724 uint32_t mVideoData; // Buffer data of the most recent video buffer 725 hidl_handle mVideoNativeHandle; // Most recent video buffer native handle 726 NotifyCallbackMsg mNotifyMessage; // Current notification message 727 728 std::mutex mTorchLock; // Synchronize access to torch status 729 std::condition_variable mTorchCond; // Condition variable for torch status 730 TorchModeStatus mTorchStatus; // Current torch status 731 732 // Holds camera registered buffers 733 std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool; 734}; 735 736Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback( 737 NotifyCallbackMsg msgType, int32_t ext1 __unused, 738 int32_t ext2 __unused) { 739 std::unique_lock<std::mutex> l(mParent->mLock); 740 mParent->mNotifyMessage = msgType; 741 mParent->mResultCondition.notify_one(); 742 743 return Void(); 744} 745 746Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory( 747 const hidl_handle& descriptor, uint32_t bufferSize, 748 uint32_t bufferCount) { 749 if (descriptor->numFds != 1) { 750 ADD_FAILURE() << "camera memory descriptor has" 751 " numFds " << descriptor->numFds << " (expect 1)" ; 752 return 0; 753 } 754 if (descriptor->data[0] < 0) { 755 ADD_FAILURE() << "camera memory descriptor has" 756 " FD " << descriptor->data[0] << " (expect >= 0)"; 757 return 0; 758 } 759 760 sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase( 761 descriptor->data[0], bufferSize*bufferCount, 0, 0); 762 mParent->mMemoryPool.emplace(pool->getHeapID(), pool); 763 764 return pool->getHeapID(); 765} 766 767Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) { 768 if (mParent->mMemoryPool.count(memId) == 0) { 769 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId); 770 ADD_FAILURE(); 771 return Void(); 772 } 773 774 mParent->mMemoryPool.erase(memId); 775 return Void(); 776} 777 778Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback( 779 DataCallbackMsg msgType __unused, uint32_t data __unused, 780 uint32_t bufferIndex __unused, 781 const CameraFrameMetadata& metadata __unused) { 782 std::unique_lock<std::mutex> l(mParent->mLock); 783 mParent->mDataMessageTypeReceived = msgType; 784 mParent->mResultCondition.notify_one(); 785 786 return Void(); 787} 788 789Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp( 790 DataCallbackMsg msgType, uint32_t data, 791 uint32_t bufferIndex, int64_t timestamp __unused) { 792 std::unique_lock<std::mutex> l(mParent->mLock); 793 mParent->mDataMessageTypeReceived = msgType; 794 mParent->mVideoBufferIndex = bufferIndex; 795 if (mParent->mMemoryPool.count(data) == 0) { 796 ADD_FAILURE() << "memory pool ID " << data << "not found"; 797 } 798 mParent->mVideoData = data; 799 mParent->mResultCondition.notify_one(); 800 801 return Void(); 802} 803 804Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp( 805 DataCallbackMsg msgType, const hidl_handle& frameData, 806 uint32_t data __unused, uint32_t bufferIndex, 807 int64_t timestamp __unused) { 808 std::unique_lock<std::mutex> l(mParent->mLock); 809 mParent->mDataMessageTypeReceived = msgType; 810 mParent->mVideoBufferIndex = bufferIndex; 811 if (mParent->mMemoryPool.count(data) == 0) { 812 ADD_FAILURE() << "memory pool ID " << data << " not found"; 813 } 814 mParent->mVideoData = data; 815 mParent->mVideoNativeHandle = frameData; 816 mParent->mResultCondition.notify_one(); 817 818 return Void(); 819} 820 821Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch( 822 DataCallbackMsg msgType, 823 const hidl_vec<HandleTimestampMessage>& batch) { 824 std::unique_lock<std::mutex> l(mParent->mLock); 825 for (auto& msg : batch) { 826 mParent->mDataMessageTypeReceived = msgType; 827 mParent->mVideoBufferIndex = msg.bufferIndex; 828 if (mParent->mMemoryPool.count(msg.data) == 0) { 829 ADD_FAILURE() << "memory pool ID " << msg.data << " not found"; 830 } 831 mParent->mVideoData = msg.data; 832 mParent->mVideoNativeHandle = msg.frameData; 833 mParent->mResultCondition.notify_one(); 834 } 835 return Void(); 836} 837 838Return<void> CameraHidlTest::DeviceCb::processCaptureResult( 839 const hidl_vec<CaptureResult>& results) { 840 if (nullptr == mParent) { 841 return Void(); 842 } 843 844 bool notify = false; 845 std::unique_lock<std::mutex> l(mParent->mLock); 846 for (size_t i = 0 ; i < results.size(); i++) { 847 uint32_t frameNumber = results[i].frameNumber; 848 849 if ((results[i].result.size() == 0) && 850 (results[i].outputBuffers.size() == 0) && 851 (results[i].inputBuffer.buffer == nullptr) && 852 (results[i].fmqResultSize == 0)) { 853 ALOGE("%s: No result data provided by HAL for frame %d result count: %d", 854 __func__, frameNumber, (int) results[i].fmqResultSize); 855 ADD_FAILURE(); 856 break; 857 } 858 859 ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber); 860 if (::android::NAME_NOT_FOUND == idx) { 861 ALOGE("%s: Unexpected frame number! received: %u", 862 __func__, frameNumber); 863 ADD_FAILURE(); 864 break; 865 } 866 867 bool isPartialResult = false; 868 bool hasInputBufferInRequest = false; 869 InFlightRequest *request = mParent->mInflightMap.editValueAt(idx); 870 ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata; 871 size_t resultSize = 0; 872 if (results[i].fmqResultSize > 0) { 873 resultMetadata.resize(results[i].fmqResultSize); 874 if (request->resultQueue == nullptr) { 875 ADD_FAILURE(); 876 break; 877 } 878 if (!request->resultQueue->read(resultMetadata.data(), 879 results[i].fmqResultSize)) { 880 ALOGE("%s: Frame %d: Cannot read camera metadata from fmq," 881 "size = %" PRIu64, __func__, frameNumber, 882 results[i].fmqResultSize); 883 ADD_FAILURE(); 884 break; 885 } 886 resultSize = resultMetadata.size(); 887 } else if (results[i].result.size() > 0) { 888 resultMetadata.setToExternal(const_cast<uint8_t *>( 889 results[i].result.data()), results[i].result.size()); 890 resultSize = resultMetadata.size(); 891 } 892 893 if (!request->usePartialResult && (resultSize > 0) && 894 (results[i].partialResult != 1)) { 895 ALOGE("%s: Result is malformed for frame %d: partial_result %u " 896 "must be 1 if partial result is not supported", __func__, 897 frameNumber, results[i].partialResult); 898 ADD_FAILURE(); 899 break; 900 } 901 902 if (results[i].partialResult != 0) { 903 request->partialResultCount = results[i].partialResult; 904 } 905 906 // Check if this result carries only partial metadata 907 if (request->usePartialResult && (resultSize > 0)) { 908 if ((results[i].partialResult > request->numPartialResults) || 909 (results[i].partialResult < 1)) { 910 ALOGE("%s: Result is malformed for frame %d: partial_result %u" 911 " must be in the range of [1, %d] when metadata is " 912 "included in the result", __func__, frameNumber, 913 results[i].partialResult, request->numPartialResults); 914 ADD_FAILURE(); 915 break; 916 } 917 request->collectedResult.append( 918 reinterpret_cast<const camera_metadata_t*>( 919 resultMetadata.data())); 920 921 isPartialResult = 922 (results[i].partialResult < request->numPartialResults); 923 } 924 925 hasInputBufferInRequest = request->hasInputBuffer; 926 927 // Did we get the (final) result metadata for this capture? 928 if ((resultSize > 0) && !isPartialResult) { 929 if (request->haveResultMetadata) { 930 ALOGE("%s: Called multiple times with metadata for frame %d", 931 __func__, frameNumber); 932 ADD_FAILURE(); 933 break; 934 } 935 request->haveResultMetadata = true; 936 request->collectedResult.sort(); 937 } 938 939 uint32_t numBuffersReturned = results[i].outputBuffers.size(); 940 if (results[i].inputBuffer.buffer != nullptr) { 941 if (hasInputBufferInRequest) { 942 numBuffersReturned += 1; 943 } else { 944 ALOGW("%s: Input buffer should be NULL if there is no input" 945 " buffer sent in the request", __func__); 946 } 947 } 948 request->numBuffersLeft -= numBuffersReturned; 949 if (request->numBuffersLeft < 0) { 950 ALOGE("%s: Too many buffers returned for frame %d", __func__, 951 frameNumber); 952 ADD_FAILURE(); 953 break; 954 } 955 956 request->resultOutputBuffers.appendArray(results[i].outputBuffers.data(), 957 results[i].outputBuffers.size()); 958 // If shutter event is received notify the pending threads. 959 if (request->shutterTimestamp != 0) { 960 notify = true; 961 } 962 } 963 964 l.unlock(); 965 if (notify) { 966 mParent->mResultCondition.notify_one(); 967 } 968 969 return Void(); 970} 971 972Return<void> CameraHidlTest::DeviceCb::notify( 973 const hidl_vec<NotifyMsg>& messages) { 974 std::lock_guard<std::mutex> l(mParent->mLock); 975 976 for (size_t i = 0; i < messages.size(); i++) { 977 ssize_t idx = mParent->mInflightMap.indexOfKey( 978 messages[i].msg.shutter.frameNumber); 979 if (::android::NAME_NOT_FOUND == idx) { 980 ALOGE("%s: Unexpected frame number! received: %u", 981 __func__, messages[i].msg.shutter.frameNumber); 982 ADD_FAILURE(); 983 break; 984 } 985 InFlightRequest *r = mParent->mInflightMap.editValueAt(idx); 986 987 switch(messages[i].type) { 988 case MsgType::ERROR: 989 if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) { 990 ALOGE("%s: Camera reported serious device error", 991 __func__); 992 ADD_FAILURE(); 993 } else { 994 r->errorCodeValid = true; 995 r->errorCode = messages[i].msg.error.errorCode; 996 r->errorStreamId = messages[i].msg.error.errorStreamId; 997 } 998 break; 999 case MsgType::SHUTTER: 1000 r->shutterTimestamp = messages[i].msg.shutter.timestamp; 1001 break; 1002 default: 1003 ALOGE("%s: Unsupported notify message %d", __func__, 1004 messages[i].type); 1005 ADD_FAILURE(); 1006 break; 1007 } 1008 } 1009 1010 mParent->mResultCondition.notify_one(); 1011 return Void(); 1012} 1013 1014hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) { 1015 hidl_vec<hidl_string> cameraDeviceNames; 1016 Return<void> ret; 1017 ret = provider->getCameraIdList( 1018 [&](auto status, const auto& idList) { 1019 ALOGI("getCameraIdList returns status:%d", (int)status); 1020 for (size_t i = 0; i < idList.size(); i++) { 1021 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str()); 1022 } 1023 ASSERT_EQ(Status::OK, status); 1024 cameraDeviceNames = idList; 1025 }); 1026 if (!ret.isOk()) { 1027 ADD_FAILURE(); 1028 } 1029 return cameraDeviceNames; 1030} 1031 1032// Test if ICameraProvider::isTorchModeSupported returns Status::OK 1033TEST_F(CameraHidlTest, isTorchModeSupported) { 1034 Return<void> ret; 1035 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1036 ret = provider.second->isSetTorchModeSupported( 1037 [&](auto status, bool support) { 1038 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", 1039 (int)status, support); 1040 ASSERT_EQ(Status::OK, status); 1041 }); 1042 ASSERT_TRUE(ret.isOk()); 1043 } 1044} 1045 1046// TODO: consider removing this test if getCameraDeviceNames() has the same coverage 1047TEST_F(CameraHidlTest, getCameraIdList) { 1048 Return<void> ret; 1049 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1050 ret = provider.second->getCameraIdList( 1051 [&](auto status, const auto& idList) { 1052 ALOGI("getCameraIdList returns status:%d", (int)status); 1053 for (size_t i = 0; i < idList.size(); i++) { 1054 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str()); 1055 } 1056 ASSERT_EQ(Status::OK, status); 1057 // This is true for internal camera provider. 1058 // Not necessary hold for external cameras providers 1059 ASSERT_GT(idList.size(), 0u); 1060 }); 1061 ASSERT_TRUE(ret.isOk()); 1062 } 1063} 1064 1065// Test if ICameraProvider::getVendorTags returns Status::OK 1066TEST_F(CameraHidlTest, getVendorTags) { 1067 Return<void> ret; 1068 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1069 ret = provider.second->getVendorTags( 1070 [&](auto status, const auto& vendorTagSecs) { 1071 ALOGI("getVendorTags returns status:%d numSections %zu", 1072 (int)status, vendorTagSecs.size()); 1073 for (size_t i = 0; i < vendorTagSecs.size(); i++) { 1074 ALOGI("Vendor tag section %zu name %s", 1075 i, vendorTagSecs[i].sectionName.c_str()); 1076 for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) { 1077 const auto& tag = vendorTagSecs[i].tags[j]; 1078 ALOGI("Vendor tag id %u name %s type %d", 1079 tag.tagId, 1080 tag.tagName.c_str(), 1081 (int) tag.tagType); 1082 } 1083 } 1084 ASSERT_EQ(Status::OK, status); 1085 }); 1086 ASSERT_TRUE(ret.isOk()); 1087 } 1088} 1089 1090// Test if ICameraProvider::setCallback returns Status::OK 1091TEST_F(CameraHidlTest, setCallback) { 1092 struct ProviderCb : public ICameraProviderCallback { 1093 virtual Return<void> cameraDeviceStatusChange( 1094 const hidl_string& cameraDeviceName, 1095 CameraDeviceStatus newStatus) override { 1096 ALOGI("camera device status callback name %s, status %d", 1097 cameraDeviceName.c_str(), (int) newStatus); 1098 return Void(); 1099 } 1100 1101 virtual Return<void> torchModeStatusChange( 1102 const hidl_string& cameraDeviceName, 1103 TorchModeStatus newStatus) override { 1104 ALOGI("Torch mode status callback name %s, status %d", 1105 cameraDeviceName.c_str(), (int) newStatus); 1106 return Void(); 1107 } 1108 }; 1109 sp<ProviderCb> cb = new ProviderCb; 1110 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1111 auto status = provider.second->setCallback(cb); 1112 ASSERT_TRUE(status.isOk()); 1113 ASSERT_EQ(Status::OK, status); 1114 } 1115} 1116 1117// Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device 1118TEST_F(CameraHidlTest, getCameraDeviceInterface) { 1119 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1120 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1121 provider.second); 1122 1123 for (const auto& name : cameraDeviceNames) { 1124 if (getCameraDeviceVersion(name, provider.first) == 1125 CAMERA_DEVICE_API_VERSION_3_2) { 1126 Return<void> ret; 1127 ret = provider.second->getCameraDeviceInterface_V3_x( 1128 name, 1129 [&](auto status, const auto& device3_2) { 1130 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 1131 (int)status); 1132 ASSERT_EQ(Status::OK, status); 1133 ASSERT_NE(device3_2, nullptr); 1134 }); 1135 ASSERT_TRUE(ret.isOk()); 1136 } else if (getCameraDeviceVersion(name, provider.first) == 1137 CAMERA_DEVICE_API_VERSION_1_0) { 1138 Return<void> ret; 1139 ret = provider.second->getCameraDeviceInterface_V1_x( 1140 name, 1141 [&](auto status, const auto& device1) { 1142 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 1143 (int)status); 1144 ASSERT_EQ(Status::OK, status); 1145 ASSERT_NE(device1, nullptr); 1146 }); 1147 ASSERT_TRUE(ret.isOk()); 1148 } 1149 } 1150 } 1151} 1152 1153// Verify that the device resource cost can be retrieved and the values are 1154// sane. 1155TEST_F(CameraHidlTest, getResourceCost) { 1156 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1157 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1158 provider.second); 1159 1160 for (const auto& name : cameraDeviceNames) { 1161 if (getCameraDeviceVersion(name, provider.first) == 1162 CAMERA_DEVICE_API_VERSION_3_2) { 1163 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; 1164 ALOGI("getResourceCost: Testing camera device %s", name.c_str()); 1165 Return<void> ret; 1166 ret = provider.second->getCameraDeviceInterface_V3_x( 1167 name, 1168 [&](auto status, const auto& device) { 1169 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 1170 (int)status); 1171 ASSERT_EQ(Status::OK, status); 1172 ASSERT_NE(device, nullptr); 1173 device3_2 = device; 1174 }); 1175 ASSERT_TRUE(ret.isOk()); 1176 1177 ret = device3_2->getResourceCost( 1178 [&](auto status, const auto& resourceCost) { 1179 ALOGI("getResourceCost returns status:%d", (int)status); 1180 ASSERT_EQ(Status::OK, status); 1181 ALOGI(" Resource cost is %d", resourceCost.resourceCost); 1182 ASSERT_LE(resourceCost.resourceCost, 100u); 1183 for (const auto& name : resourceCost.conflictingDevices) { 1184 ALOGI(" Conflicting device: %s", name.c_str()); 1185 } 1186 }); 1187 ASSERT_TRUE(ret.isOk()); 1188 } else { 1189 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1190 ALOGI("getResourceCost: Testing camera device %s", name.c_str()); 1191 Return<void> ret; 1192 ret = provider.second->getCameraDeviceInterface_V1_x( 1193 name, 1194 [&](auto status, const auto& device) { 1195 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 1196 (int)status); 1197 ASSERT_EQ(Status::OK, status); 1198 ASSERT_NE(device, nullptr); 1199 device1 = device; 1200 }); 1201 ASSERT_TRUE(ret.isOk()); 1202 1203 ret = device1->getResourceCost( 1204 [&](auto status, const auto& resourceCost) { 1205 ALOGI("getResourceCost returns status:%d", (int)status); 1206 ASSERT_EQ(Status::OK, status); 1207 ALOGI(" Resource cost is %d", 1208 resourceCost.resourceCost); 1209 ASSERT_LE(resourceCost.resourceCost, 100u); 1210 for (const auto& name : resourceCost.conflictingDevices) { 1211 ALOGI(" Conflicting device: %s", name.c_str()); 1212 } 1213 }); 1214 ASSERT_TRUE(ret.isOk()); 1215 } 1216 } 1217 } 1218} 1219 1220// Verify that the static camera info can be retrieved 1221// successfully. 1222TEST_F(CameraHidlTest, getCameraInfo) { 1223 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1224 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1225 provider.second); 1226 1227 for (const auto& name : cameraDeviceNames) { 1228 if (getCameraDeviceVersion(name, provider.first) == 1229 CAMERA_DEVICE_API_VERSION_1_0) { 1230 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1231 ALOGI("getCameraCharacteristics: Testing camera device %s", 1232 name.c_str()); 1233 Return<void> ret; 1234 ret = provider.second->getCameraDeviceInterface_V1_x( 1235 name, 1236 [&](auto status, const auto& device) { 1237 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 1238 (int)status); 1239 ASSERT_EQ(Status::OK, status); 1240 ASSERT_NE(device, nullptr); 1241 device1 = device; 1242 }); 1243 ASSERT_TRUE(ret.isOk()); 1244 1245 ret = device1->getCameraInfo( 1246 [&](auto status, const auto& info) { 1247 ALOGI("getCameraInfo returns status:%d", (int)status); 1248 ASSERT_EQ(Status::OK, status); 1249 switch(info.orientation) { 1250 case 0: 1251 case 90: 1252 case 180: 1253 case 270: 1254 //Expected cases 1255 ALOGI("camera orientation: %d", info.orientation); 1256 break; 1257 default: 1258 FAIL() << "Unexpected camera orientation:" << info.orientation; 1259 } 1260 switch(info.facing) { 1261 case CameraFacing::BACK: 1262 case CameraFacing::FRONT: 1263 case CameraFacing::EXTERNAL: 1264 //Expected cases 1265 ALOGI("camera facing: %d", info.facing); 1266 break; 1267 default: 1268 FAIL() << "Unexpected camera facing:" << static_cast<uint32_t> ( 1269 info.facing); 1270 } 1271 }); 1272 ASSERT_TRUE(ret.isOk()); 1273 } 1274 } 1275 } 1276} 1277 1278// Check whether preview window can be configured 1279TEST_F(CameraHidlTest, setPreviewWindow) { 1280 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1281 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1282 provider.second); 1283 1284 for (const auto& name : cameraDeviceNames) { 1285 if (getCameraDeviceVersion(name, provider.first) == 1286 CAMERA_DEVICE_API_VERSION_1_0) { 1287 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1288 openCameraDevice(name, provider.second, &device1 /*out*/); 1289 ASSERT_NE(nullptr, device1.get()); 1290 sp<BufferItemConsumer> bufferItemConsumer; 1291 sp<BufferItemHander> bufferHandler; 1292 setupPreviewWindow(device1, 1293 &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1294 1295 Return<void> ret; 1296 ret = device1->close(); 1297 ASSERT_TRUE(ret.isOk()); 1298 } 1299 } 1300 } 1301} 1302 1303// Verify that setting preview window fails in case device is not open 1304TEST_F(CameraHidlTest, setPreviewWindowInvalid) { 1305 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1306 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1307 provider.second); 1308 1309 for (const auto& name : cameraDeviceNames) { 1310 if (getCameraDeviceVersion(name, provider.first) == 1311 CAMERA_DEVICE_API_VERSION_1_0) { 1312 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1313 ALOGI("getCameraCharacteristics: Testing camera device %s", 1314 name.c_str()); 1315 Return<void> ret; 1316 ret = provider.second->getCameraDeviceInterface_V1_x( 1317 name, 1318 [&](auto status, const auto& device) { 1319 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 1320 (int)status); 1321 ASSERT_EQ(Status::OK, status); 1322 ASSERT_NE(device, nullptr); 1323 device1 = device; 1324 }); 1325 ASSERT_TRUE(ret.isOk()); 1326 1327 Return<Status> returnStatus = device1->setPreviewWindow(nullptr); 1328 ASSERT_TRUE(returnStatus.isOk()); 1329 ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus); 1330 } 1331 } 1332 } 1333} 1334 1335// Start and stop preview checking whether it gets enabled in between. 1336TEST_F(CameraHidlTest, startStopPreview) { 1337 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1338 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1339 provider.second); 1340 1341 for (const auto& name : cameraDeviceNames) { 1342 if (getCameraDeviceVersion(name, provider.first) == 1343 CAMERA_DEVICE_API_VERSION_1_0) { 1344 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1345 openCameraDevice(name, provider.second, &device1 /*out*/); 1346 ASSERT_NE(nullptr, device1.get()); 1347 sp<BufferItemConsumer> bufferItemConsumer; 1348 sp<BufferItemHander> bufferHandler; 1349 setupPreviewWindow(device1, 1350 &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1351 1352 startPreview(device1); 1353 1354 Return<bool> returnBoolStatus = device1->previewEnabled(); 1355 ASSERT_TRUE(returnBoolStatus.isOk()); 1356 ASSERT_TRUE(returnBoolStatus); 1357 1358 stopPreviewAndClose(device1); 1359 } 1360 } 1361 } 1362} 1363 1364// Start preview without active preview window. Preview should start as soon 1365// as a valid active window gets configured. 1366TEST_F(CameraHidlTest, startStopPreviewDelayed) { 1367 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1368 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1369 provider.second); 1370 1371 for (const auto& name : cameraDeviceNames) { 1372 if (getCameraDeviceVersion(name, provider.first) == 1373 CAMERA_DEVICE_API_VERSION_1_0) { 1374 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1375 openCameraDevice(name, provider.second, &device1 /*out*/); 1376 ASSERT_NE(nullptr, device1.get()); 1377 1378 Return<Status> returnStatus = device1->setPreviewWindow(nullptr); 1379 ASSERT_TRUE(returnStatus.isOk()); 1380 ASSERT_EQ(Status::OK, returnStatus); 1381 1382 startPreview(device1); 1383 1384 sp<BufferItemConsumer> bufferItemConsumer; 1385 sp<BufferItemHander> bufferHandler; 1386 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1387 &bufferHandler /*out*/); 1388 1389 //Preview should get enabled now 1390 Return<bool> returnBoolStatus = device1->previewEnabled(); 1391 ASSERT_TRUE(returnBoolStatus.isOk()); 1392 ASSERT_TRUE(returnBoolStatus); 1393 1394 stopPreviewAndClose(device1); 1395 } 1396 } 1397 } 1398} 1399 1400// Verify that image capture behaves as expected along with preview callbacks. 1401TEST_F(CameraHidlTest, takePicture) { 1402 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1403 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1404 provider.second); 1405 1406 for (const auto& name : cameraDeviceNames) { 1407 if (getCameraDeviceVersion(name, provider.first) == 1408 CAMERA_DEVICE_API_VERSION_1_0) { 1409 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1410 openCameraDevice(name, provider.second, &device1 /*out*/); 1411 ASSERT_NE(nullptr, device1.get()); 1412 sp<BufferItemConsumer> bufferItemConsumer; 1413 sp<BufferItemHander> bufferHandler; 1414 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1415 &bufferHandler /*out*/); 1416 1417 { 1418 std::unique_lock<std::mutex> l(mLock); 1419 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1420 } 1421 1422 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, 1423 device1); 1424 startPreview(device1); 1425 1426 { 1427 std::unique_lock<std::mutex> l(mLock); 1428 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l); 1429 } 1430 1431 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, 1432 device1); 1433 enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, 1434 device1); 1435 1436 { 1437 std::unique_lock<std::mutex> l(mLock); 1438 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1439 } 1440 1441 Return<Status> returnStatus = device1->takePicture(); 1442 ASSERT_TRUE(returnStatus.isOk()); 1443 ASSERT_EQ(Status::OK, returnStatus); 1444 1445 { 1446 std::unique_lock<std::mutex> l(mLock); 1447 waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l); 1448 } 1449 1450 disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, 1451 device1); 1452 stopPreviewAndClose(device1); 1453 } 1454 } 1455 } 1456} 1457 1458// Image capture should fail in case preview didn't get enabled first. 1459TEST_F(CameraHidlTest, takePictureFail) { 1460 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1461 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1462 provider.second); 1463 1464 for (const auto& name : cameraDeviceNames) { 1465 if (getCameraDeviceVersion(name, provider.first) == 1466 CAMERA_DEVICE_API_VERSION_1_0) { 1467 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1468 openCameraDevice(name, provider.second, &device1 /*out*/); 1469 ASSERT_NE(nullptr, device1.get()); 1470 1471 Return<Status> returnStatus = device1->takePicture(); 1472 ASSERT_TRUE(returnStatus.isOk()); 1473 ASSERT_NE(Status::OK, returnStatus); 1474 1475 Return<void> ret = device1->close(); 1476 ASSERT_TRUE(ret.isOk()); 1477 } 1478 } 1479 } 1480} 1481 1482// Verify that image capture can be cancelled. 1483TEST_F(CameraHidlTest, cancelPicture) { 1484 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1485 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1486 provider.second); 1487 1488 for (const auto& name : cameraDeviceNames) { 1489 if (getCameraDeviceVersion(name, provider.first) == 1490 CAMERA_DEVICE_API_VERSION_1_0) { 1491 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1492 openCameraDevice(name, provider.second, &device1 /*out*/); 1493 ASSERT_NE(nullptr, device1.get()); 1494 sp<BufferItemConsumer> bufferItemConsumer; 1495 sp<BufferItemHander> bufferHandler; 1496 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1497 &bufferHandler /*out*/); 1498 startPreview(device1); 1499 1500 Return<Status> returnStatus = device1->takePicture(); 1501 ASSERT_TRUE(returnStatus.isOk()); 1502 ASSERT_EQ(Status::OK, returnStatus); 1503 1504 returnStatus = device1->cancelPicture(); 1505 ASSERT_TRUE(returnStatus.isOk()); 1506 ASSERT_EQ(Status::OK, returnStatus); 1507 1508 stopPreviewAndClose(device1); 1509 } 1510 } 1511 } 1512} 1513 1514// Image capture cancel should fail when image capture is not running. 1515TEST_F(CameraHidlTest, cancelPictureFail) { 1516 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1517 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1518 provider.second); 1519 1520 for (const auto& name : cameraDeviceNames) { 1521 if (getCameraDeviceVersion(name, provider.first) == 1522 CAMERA_DEVICE_API_VERSION_1_0) { 1523 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1524 openCameraDevice(name, provider.second, &device1 /*out*/); 1525 ASSERT_NE(nullptr, device1.get()); 1526 sp<BufferItemConsumer> bufferItemConsumer; 1527 sp<BufferItemHander> bufferHandler; 1528 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1529 &bufferHandler /*out*/); 1530 startPreview(device1); 1531 1532 Return<Status> returnStatus = device1->cancelPicture(); 1533 ASSERT_TRUE(returnStatus.isOk()); 1534 ASSERT_NE(Status::OK, returnStatus); 1535 1536 stopPreviewAndClose(device1); 1537 } 1538 } 1539 } 1540} 1541 1542// Test basic video recording. 1543TEST_F(CameraHidlTest, startStopRecording) { 1544 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1545 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1546 provider.second); 1547 1548 for (const auto& name : cameraDeviceNames) { 1549 if (getCameraDeviceVersion(name, provider.first) == 1550 CAMERA_DEVICE_API_VERSION_1_0) { 1551 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1552 openCameraDevice(name, provider.second, &device1 /*out*/); 1553 ASSERT_NE(nullptr, device1.get()); 1554 sp<BufferItemConsumer> bufferItemConsumer; 1555 sp<BufferItemHander> bufferHandler; 1556 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1557 &bufferHandler /*out*/); 1558 1559 { 1560 std::unique_lock<std::mutex> l(mLock); 1561 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1562 } 1563 1564 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, 1565 device1); 1566 startPreview(device1); 1567 1568 { 1569 std::unique_lock<std::mutex> l(mLock); 1570 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l); 1571 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1572 mVideoBufferIndex = UINT32_MAX; 1573 } 1574 1575 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, 1576 device1); 1577 1578 bool videoMetaEnabled = false; 1579 Return<Status> returnStatus = device1->storeMetaDataInBuffers( 1580 true); 1581 ASSERT_TRUE(returnStatus.isOk()); 1582 // It is allowed for devices to not support this feature 1583 ASSERT_TRUE((Status::OK == returnStatus) || 1584 (Status::OPERATION_NOT_SUPPORTED == returnStatus)); 1585 if (Status::OK == returnStatus) { 1586 videoMetaEnabled = true; 1587 } 1588 1589 enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, 1590 device1); 1591 Return<bool> returnBoolStatus = device1->recordingEnabled(); 1592 ASSERT_TRUE(returnBoolStatus.isOk()); 1593 ASSERT_FALSE(returnBoolStatus); 1594 1595 returnStatus = device1->startRecording(); 1596 ASSERT_TRUE(returnStatus.isOk()); 1597 ASSERT_EQ(Status::OK, returnStatus); 1598 1599 { 1600 std::unique_lock<std::mutex> l(mLock); 1601 waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l); 1602 ASSERT_NE(UINT32_MAX, mVideoBufferIndex); 1603 disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, 1604 device1); 1605 } 1606 1607 returnBoolStatus = device1->recordingEnabled(); 1608 ASSERT_TRUE(returnBoolStatus.isOk()); 1609 ASSERT_TRUE(returnBoolStatus); 1610 1611 Return<void> ret; 1612 if (videoMetaEnabled) { 1613 ret = device1->releaseRecordingFrameHandle(mVideoData, 1614 mVideoBufferIndex, mVideoNativeHandle); 1615 ASSERT_TRUE(ret.isOk()); 1616 } else { 1617 ret = device1->releaseRecordingFrame(mVideoData, 1618 mVideoBufferIndex); 1619 ASSERT_TRUE(ret.isOk()); 1620 } 1621 1622 ret = device1->stopRecording(); 1623 ASSERT_TRUE(ret.isOk()); 1624 1625 stopPreviewAndClose(device1); 1626 } 1627 } 1628 } 1629} 1630 1631// It shouldn't be possible to start recording without enabling preview first. 1632TEST_F(CameraHidlTest, startRecordingFail) { 1633 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1634 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1635 provider.second); 1636 1637 for (const auto& name : cameraDeviceNames) { 1638 if (getCameraDeviceVersion(name, provider.first) == 1639 CAMERA_DEVICE_API_VERSION_1_0) { 1640 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1641 openCameraDevice(name, provider.second, &device1 /*out*/); 1642 ASSERT_NE(nullptr, device1.get()); 1643 1644 Return<bool> returnBoolStatus = device1->recordingEnabled(); 1645 ASSERT_TRUE(returnBoolStatus.isOk()); 1646 ASSERT_FALSE(returnBoolStatus); 1647 1648 Return<Status> returnStatus = device1->startRecording(); 1649 ASSERT_TRUE(returnStatus.isOk()); 1650 ASSERT_NE(Status::OK, returnStatus); 1651 1652 Return<void> ret = device1->close(); 1653 ASSERT_TRUE(ret.isOk()); 1654 } 1655 } 1656 } 1657} 1658 1659// Check autofocus support if available. 1660TEST_F(CameraHidlTest, autoFocus) { 1661 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1662 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1663 provider.second); 1664 std::vector<const char *> focusModes = {CameraParameters::FOCUS_MODE_AUTO, 1665 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, 1666 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO}; 1667 1668 for (const auto& name : cameraDeviceNames) { 1669 if (getCameraDeviceVersion(name, provider.first) == 1670 CAMERA_DEVICE_API_VERSION_1_0) { 1671 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1672 openCameraDevice(name, provider.second, &device1 /*out*/); 1673 ASSERT_NE(nullptr, device1.get()); 1674 1675 ::android::CameraParameters cameraParams; 1676 getParameters(device1, &cameraParams /*out*/); 1677 1678 if (Status::OK != isAutoFocusModeAvailable(cameraParams, 1679 CameraParameters::FOCUS_MODE_AUTO)) { 1680 Return<void> ret = device1->close(); 1681 ASSERT_TRUE(ret.isOk()); 1682 continue; 1683 } 1684 1685 sp<BufferItemConsumer> bufferItemConsumer; 1686 sp<BufferItemHander> bufferHandler; 1687 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1688 &bufferHandler /*out*/); 1689 startPreview(device1); 1690 enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1); 1691 1692 for (auto &iter : focusModes) { 1693 if (Status::OK != isAutoFocusModeAvailable(cameraParams, 1694 iter)) { 1695 continue; 1696 } 1697 1698 cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter); 1699 setParameters(device1, cameraParams); 1700 { 1701 std::unique_lock<std::mutex> l(mLock); 1702 mNotifyMessage = NotifyCallbackMsg::ERROR; 1703 } 1704 1705 Return<Status> returnStatus = device1->autoFocus(); 1706 ASSERT_TRUE(returnStatus.isOk()); 1707 ASSERT_EQ(Status::OK, returnStatus); 1708 1709 { 1710 std::unique_lock<std::mutex> l(mLock); 1711 while (NotifyCallbackMsg::FOCUS != mNotifyMessage) { 1712 auto timeout = std::chrono::system_clock::now() + 1713 std::chrono::seconds(kAutoFocusTimeoutSec); 1714 ASSERT_NE(std::cv_status::timeout, 1715 mResultCondition.wait_until(l, timeout)); 1716 } 1717 } 1718 } 1719 1720 disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1); 1721 stopPreviewAndClose(device1); 1722 } 1723 } 1724 } 1725} 1726 1727// In case autofocus is supported verify that it can be cancelled. 1728TEST_F(CameraHidlTest, cancelAutoFocus) { 1729 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1730 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1731 provider.second); 1732 1733 for (const auto& name : cameraDeviceNames) { 1734 if (getCameraDeviceVersion(name, provider.first) == 1735 CAMERA_DEVICE_API_VERSION_1_0) { 1736 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1737 openCameraDevice(name, provider.second, &device1 /*out*/); 1738 ASSERT_NE(nullptr, device1.get()); 1739 1740 ::android::CameraParameters cameraParams; 1741 getParameters(device1, &cameraParams /*out*/); 1742 1743 if (Status::OK != isAutoFocusModeAvailable(cameraParams, 1744 CameraParameters::FOCUS_MODE_AUTO)) { 1745 Return<void> ret = device1->close(); 1746 ASSERT_TRUE(ret.isOk()); 1747 continue; 1748 } 1749 1750 // It should be fine to call before preview starts. 1751 ASSERT_EQ(Status::OK, device1->cancelAutoFocus()); 1752 1753 sp<BufferItemConsumer> bufferItemConsumer; 1754 sp<BufferItemHander> bufferHandler; 1755 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1756 &bufferHandler /*out*/); 1757 startPreview(device1); 1758 1759 // It should be fine to call after preview starts too. 1760 Return<Status> returnStatus = device1->cancelAutoFocus(); 1761 ASSERT_TRUE(returnStatus.isOk()); 1762 ASSERT_EQ(Status::OK, returnStatus); 1763 1764 returnStatus = device1->autoFocus(); 1765 ASSERT_TRUE(returnStatus.isOk()); 1766 ASSERT_EQ(Status::OK, returnStatus); 1767 1768 returnStatus = device1->cancelAutoFocus(); 1769 ASSERT_TRUE(returnStatus.isOk()); 1770 ASSERT_EQ(Status::OK, returnStatus); 1771 1772 stopPreviewAndClose(device1); 1773 } 1774 } 1775 } 1776} 1777 1778// Check whether face detection is available and try to enable&disable. 1779TEST_F(CameraHidlTest, sendCommandFaceDetection) { 1780 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1781 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1782 provider.second); 1783 1784 for (const auto& name : cameraDeviceNames) { 1785 if (getCameraDeviceVersion(name, provider.first) == 1786 CAMERA_DEVICE_API_VERSION_1_0) { 1787 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1788 openCameraDevice(name, provider.second, &device1 /*out*/); 1789 ASSERT_NE(nullptr, device1.get()); 1790 1791 ::android::CameraParameters cameraParams; 1792 getParameters(device1, &cameraParams /*out*/); 1793 1794 int32_t hwFaces = cameraParams.getInt( 1795 CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW); 1796 int32_t swFaces = cameraParams.getInt( 1797 CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW); 1798 if ((0 >= hwFaces) && (0 >= swFaces)) { 1799 Return<void> ret = device1->close(); 1800 ASSERT_TRUE(ret.isOk()); 1801 continue; 1802 } 1803 1804 sp<BufferItemConsumer> bufferItemConsumer; 1805 sp<BufferItemHander> bufferHandler; 1806 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1807 &bufferHandler /*out*/); 1808 startPreview(device1); 1809 1810 if (0 < hwFaces) { 1811 Return<Status> returnStatus = device1->sendCommand( 1812 CommandType::START_FACE_DETECTION, 1813 CAMERA_FACE_DETECTION_HW, 0); 1814 ASSERT_TRUE(returnStatus.isOk()); 1815 ASSERT_EQ(Status::OK, returnStatus); 1816 // TODO(epeev) : Enable and check for face notifications 1817 returnStatus = device1->sendCommand( 1818 CommandType::STOP_FACE_DETECTION, 1819 CAMERA_FACE_DETECTION_HW, 0); 1820 ASSERT_TRUE(returnStatus.isOk()); 1821 ASSERT_EQ(Status::OK, returnStatus); 1822 } 1823 1824 if (0 < swFaces) { 1825 Return<Status> returnStatus = device1->sendCommand( 1826 CommandType::START_FACE_DETECTION, 1827 CAMERA_FACE_DETECTION_SW, 0); 1828 ASSERT_TRUE(returnStatus.isOk()); 1829 ASSERT_EQ(Status::OK, returnStatus); 1830 // TODO(epeev) : Enable and check for face notifications 1831 returnStatus = device1->sendCommand( 1832 CommandType::STOP_FACE_DETECTION, 1833 CAMERA_FACE_DETECTION_SW, 0); 1834 ASSERT_TRUE(returnStatus.isOk()); 1835 ASSERT_EQ(Status::OK, returnStatus); 1836 } 1837 1838 stopPreviewAndClose(device1); 1839 } 1840 } 1841 } 1842} 1843 1844// Check whether smooth zoom is available and try to enable&disable. 1845TEST_F(CameraHidlTest, sendCommandSmoothZoom) { 1846 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1847 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1848 provider.second); 1849 1850 for (const auto& name : cameraDeviceNames) { 1851 if (getCameraDeviceVersion(name, provider.first) == 1852 CAMERA_DEVICE_API_VERSION_1_0) { 1853 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1854 openCameraDevice(name, provider.second, &device1 /*out*/); 1855 ASSERT_NE(nullptr, device1.get()); 1856 1857 ::android::CameraParameters cameraParams; 1858 getParameters(device1, &cameraParams /*out*/); 1859 1860 const char *smoothZoomStr = cameraParams.get( 1861 CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED); 1862 bool smoothZoomSupported = ((nullptr != smoothZoomStr) && 1863 (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) ? 1864 true : false; 1865 if (!smoothZoomSupported) { 1866 Return<void> ret = device1->close(); 1867 ASSERT_TRUE(ret.isOk()); 1868 continue; 1869 } 1870 1871 int32_t maxZoom = cameraParams.getInt( 1872 CameraParameters::KEY_MAX_ZOOM); 1873 ASSERT_TRUE(0 < maxZoom); 1874 1875 sp<BufferItemConsumer> bufferItemConsumer; 1876 sp<BufferItemHander> bufferHandler; 1877 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, 1878 &bufferHandler /*out*/); 1879 startPreview(device1); 1880 setParameters(device1, cameraParams); 1881 1882 Return<Status> returnStatus = device1->sendCommand( 1883 CommandType::START_SMOOTH_ZOOM, maxZoom, 0); 1884 ASSERT_TRUE(returnStatus.isOk()); 1885 ASSERT_EQ(Status::OK, returnStatus); 1886 // TODO(epeev) : Enable and check for face notifications 1887 returnStatus = device1->sendCommand( 1888 CommandType::STOP_SMOOTH_ZOOM, 0, 0); 1889 ASSERT_TRUE(returnStatus.isOk()); 1890 ASSERT_EQ(Status::OK, returnStatus); 1891 1892 stopPreviewAndClose(device1); 1893 } 1894 } 1895 } 1896} 1897 1898// Basic sanity tests related to camera parameters. 1899TEST_F(CameraHidlTest, getSetParameters) { 1900 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 1901 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 1902 provider.second); 1903 1904 for (const auto& name : cameraDeviceNames) { 1905 if (getCameraDeviceVersion(name, provider.first) == 1906 CAMERA_DEVICE_API_VERSION_1_0) { 1907 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1908 openCameraDevice(name, provider.second, &device1 /*out*/); 1909 ASSERT_NE(nullptr, device1.get()); 1910 1911 ::android::CameraParameters cameraParams; 1912 getParameters(device1, &cameraParams /*out*/); 1913 1914 int32_t width, height; 1915 cameraParams.getPictureSize(&width, &height); 1916 ASSERT_TRUE((0 < width) && (0 < height)); 1917 cameraParams.getPreviewSize(&width, &height); 1918 ASSERT_TRUE((0 < width) && (0 < height)); 1919 int32_t minFps, maxFps; 1920 cameraParams.getPreviewFpsRange(&minFps, &maxFps); 1921 ASSERT_TRUE((0 < minFps) && (0 < maxFps)); 1922 ASSERT_NE(nullptr, cameraParams.getPreviewFormat()); 1923 ASSERT_NE(nullptr, cameraParams.getPictureFormat()); 1924 ASSERT_TRUE(strcmp(CameraParameters::PIXEL_FORMAT_JPEG, 1925 cameraParams.getPictureFormat()) == 0); 1926 1927 const char *flashMode = cameraParams.get( 1928 CameraParameters::KEY_FLASH_MODE); 1929 ASSERT_TRUE((nullptr == flashMode) || (strcmp( 1930 CameraParameters::FLASH_MODE_OFF, flashMode) == 0)); 1931 1932 const char *wbMode = cameraParams.get( 1933 CameraParameters::KEY_WHITE_BALANCE); 1934 ASSERT_TRUE((nullptr == wbMode) || (strcmp( 1935 CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0)); 1936 1937 const char *effect = cameraParams.get( 1938 CameraParameters::KEY_EFFECT); 1939 ASSERT_TRUE((nullptr == effect) || (strcmp( 1940 CameraParameters::EFFECT_NONE, effect) == 0)); 1941 1942 ::android::Vector<::android::Size> previewSizes; 1943 cameraParams.getSupportedPreviewSizes(previewSizes); 1944 ASSERT_FALSE(previewSizes.empty()); 1945 ::android::Vector<::android::Size> pictureSizes; 1946 cameraParams.getSupportedPictureSizes(pictureSizes); 1947 ASSERT_FALSE(pictureSizes.empty()); 1948 const char *previewFormats = cameraParams.get( 1949 CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS); 1950 ASSERT_NE(nullptr, previewFormats); 1951 ::android::String8 previewFormatsString(previewFormats); 1952 ASSERT_TRUE(previewFormatsString.contains( 1953 CameraParameters::PIXEL_FORMAT_YUV420SP)); 1954 ASSERT_NE(nullptr, cameraParams.get( 1955 CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS)); 1956 ASSERT_NE(nullptr, cameraParams.get( 1957 CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)); 1958 const char *focusModes = cameraParams.get( 1959 CameraParameters::KEY_SUPPORTED_FOCUS_MODES); 1960 ASSERT_NE(nullptr, focusModes); 1961 ::android::String8 focusModesString(focusModes); 1962 const char *focusMode = cameraParams.get( 1963 CameraParameters::KEY_FOCUS_MODE); 1964 ASSERT_NE(nullptr, focusMode); 1965 // Auto focus mode should be default 1966 if (focusModesString.contains( 1967 CameraParameters::FOCUS_MODE_AUTO)) { 1968 ASSERT_TRUE(strcmp( 1969 CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0); 1970 } 1971 ASSERT_TRUE(0 < cameraParams.getInt( 1972 CameraParameters::KEY_FOCAL_LENGTH)); 1973 int32_t horizontalViewAngle = cameraParams.getInt( 1974 CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE); 1975 ASSERT_TRUE((0 < horizontalViewAngle) && 1976 (360 >= horizontalViewAngle)); 1977 int32_t verticalViewAngle = cameraParams.getInt( 1978 CameraParameters::KEY_VERTICAL_VIEW_ANGLE); 1979 ASSERT_TRUE((0 < verticalViewAngle) && 1980 (360 >= verticalViewAngle)); 1981 int32_t jpegQuality = cameraParams.getInt( 1982 CameraParameters::KEY_JPEG_QUALITY); 1983 ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality)); 1984 int32_t jpegThumbQuality = cameraParams.getInt( 1985 CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); 1986 ASSERT_TRUE((1 <= jpegThumbQuality) && 1987 (100 >= jpegThumbQuality)); 1988 1989 cameraParams.setPictureSize(pictureSizes[0].width, 1990 pictureSizes[0].height); 1991 cameraParams.setPreviewSize(previewSizes[0].width, 1992 previewSizes[0].height); 1993 1994 setParameters(device1, cameraParams); 1995 getParameters(device1, &cameraParams /*out*/); 1996 1997 cameraParams.getPictureSize(&width, &height); 1998 ASSERT_TRUE((pictureSizes[0].width == width) && 1999 (pictureSizes[0].height == height)); 2000 cameraParams.getPreviewSize(&width, &height); 2001 ASSERT_TRUE((previewSizes[0].width == width) && 2002 (previewSizes[0].height == height)); 2003 2004 Return<void> ret = device1->close(); 2005 ASSERT_TRUE(ret.isOk()); 2006 } 2007 } 2008 } 2009} 2010 2011// Verify that the static camera characteristics can be retrieved 2012// successfully. 2013TEST_F(CameraHidlTest, getCameraCharacteristics) { 2014 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2015 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2016 provider.second); 2017 2018 for (const auto& name : cameraDeviceNames) { 2019 if (getCameraDeviceVersion(name, provider.first) == 2020 CAMERA_DEVICE_API_VERSION_3_2) { 2021 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; 2022 ALOGI("getCameraCharacteristics: Testing camera device %s", 2023 name.c_str()); 2024 Return<void> ret; 2025 ret = provider.second->getCameraDeviceInterface_V3_x( 2026 name, 2027 [&](auto status, const auto& device) { 2028 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 2029 (int)status); 2030 ASSERT_EQ(Status::OK, status); 2031 ASSERT_NE(device, nullptr); 2032 device3_2 = device; 2033 }); 2034 ASSERT_TRUE(ret.isOk()); 2035 2036 ret = device3_2->getCameraCharacteristics( 2037 [&](auto status, const auto& chars) { 2038 ALOGI("getCameraCharacteristics returns status:%d", 2039 (int)status); 2040 ASSERT_EQ(Status::OK, status); 2041 const camera_metadata_t* metadata = 2042 (camera_metadata_t*) chars.data(); 2043 size_t expectedSize = chars.size(); 2044 int result = validate_camera_metadata_structure( 2045 metadata, &expectedSize); 2046 ASSERT_TRUE((result == 0) || 2047 (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 2048 size_t entryCount = get_camera_metadata_entry_count( 2049 metadata); 2050 // TODO: we can do better than 0 here. Need to check how many required 2051 // characteristics keys we've defined. 2052 ASSERT_GT(entryCount, 0u); 2053 ALOGI("getCameraCharacteristics metadata entry count is %zu", 2054 entryCount); 2055 }); 2056 ASSERT_TRUE(ret.isOk()); 2057 } 2058 } 2059 } 2060} 2061 2062//In case it is supported verify that torch can be enabled. 2063//Check for corresponding toch callbacks as well. 2064TEST_F(CameraHidlTest, setTorchMode) { 2065 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2066 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2067 provider.second); 2068 bool torchControlSupported = false; 2069 Return<void> ret; 2070 2071 ret = provider.second->isSetTorchModeSupported( 2072 [&](auto status, bool support) { 2073 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", 2074 (int)status, support); 2075 ASSERT_EQ(Status::OK, status); 2076 torchControlSupported = support; 2077 }); 2078 2079 2080 sp<TorchProviderCb> cb = new TorchProviderCb(this); 2081 Return<Status> returnStatus = provider.second->setCallback(cb); 2082 ASSERT_TRUE(returnStatus.isOk()); 2083 ASSERT_EQ(Status::OK, returnStatus); 2084 2085 for (const auto& name : cameraDeviceNames) { 2086 if (getCameraDeviceVersion(name, provider.first) == 2087 CAMERA_DEVICE_API_VERSION_3_2) { 2088 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; 2089 ALOGI("setTorchMode: Testing camera device %s", name.c_str()); 2090 ret = provider.second->getCameraDeviceInterface_V3_x( 2091 name, 2092 [&](auto status, const auto& device) { 2093 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 2094 (int)status); 2095 ASSERT_EQ(Status::OK, status); 2096 ASSERT_NE(device, nullptr); 2097 device3_2 = device; 2098 }); 2099 ASSERT_TRUE(ret.isOk()); 2100 2101 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2102 returnStatus = device3_2->setTorchMode(TorchMode::ON); 2103 ASSERT_TRUE(returnStatus.isOk()); 2104 if (!torchControlSupported) { 2105 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus); 2106 } else { 2107 ASSERT_TRUE(returnStatus == Status::OK || 2108 returnStatus == Status::OPERATION_NOT_SUPPORTED); 2109 if (returnStatus == Status::OK) { 2110 { 2111 std::unique_lock<std::mutex> l(mTorchLock); 2112 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2113 auto timeout = std::chrono::system_clock::now() + 2114 std::chrono::seconds(kTorchTimeoutSec); 2115 ASSERT_NE(std::cv_status::timeout, 2116 mTorchCond.wait_until(l, timeout)); 2117 } 2118 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, 2119 mTorchStatus); 2120 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2121 } 2122 2123 returnStatus = device3_2->setTorchMode(TorchMode::OFF); 2124 ASSERT_TRUE(returnStatus.isOk()); 2125 ASSERT_EQ(Status::OK, returnStatus); 2126 2127 { 2128 std::unique_lock<std::mutex> l(mTorchLock); 2129 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2130 auto timeout = std::chrono::system_clock::now() + 2131 std::chrono::seconds(kTorchTimeoutSec); 2132 ASSERT_NE(std::cv_status::timeout, 2133 mTorchCond.wait_until(l, timeout)); 2134 } 2135 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, 2136 mTorchStatus); 2137 } 2138 } 2139 } 2140 } else if (getCameraDeviceVersion(name, provider.first) == 2141 CAMERA_DEVICE_API_VERSION_1_0) { 2142 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2143 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2144 ret = provider.second->getCameraDeviceInterface_V1_x( 2145 name, 2146 [&](auto status, const auto& device) { 2147 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 2148 (int)status); 2149 ASSERT_EQ(Status::OK, status); 2150 ASSERT_NE(device, nullptr); 2151 device1 = device; 2152 }); 2153 ASSERT_TRUE(ret.isOk()); 2154 2155 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2156 returnStatus = device1->setTorchMode(TorchMode::ON); 2157 ASSERT_TRUE(returnStatus.isOk()); 2158 if (!torchControlSupported) { 2159 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus); 2160 } else { 2161 ASSERT_TRUE(returnStatus == Status::OK || 2162 returnStatus == Status::OPERATION_NOT_SUPPORTED); 2163 if (returnStatus == Status::OK) { 2164 { 2165 std::unique_lock<std::mutex> l(mTorchLock); 2166 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2167 auto timeout = std::chrono::system_clock::now() + 2168 std::chrono::seconds(kTorchTimeoutSec); 2169 ASSERT_NE(std::cv_status::timeout, 2170 mTorchCond.wait_until(l, timeout)); 2171 } 2172 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, 2173 mTorchStatus); 2174 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2175 } 2176 2177 returnStatus = device1->setTorchMode(TorchMode::OFF); 2178 ASSERT_TRUE(returnStatus.isOk()); 2179 ASSERT_EQ(Status::OK, returnStatus); 2180 2181 { 2182 std::unique_lock<std::mutex> l(mTorchLock); 2183 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2184 auto timeout = std::chrono::system_clock::now() + 2185 std::chrono::seconds(kTorchTimeoutSec); 2186 ASSERT_NE(std::cv_status::timeout, 2187 mTorchCond.wait_until(l, timeout)); 2188 } 2189 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, 2190 mTorchStatus); 2191 } 2192 } 2193 } 2194 ret = device1->close(); 2195 ASSERT_TRUE(ret.isOk()); 2196 } 2197 } 2198 2199 returnStatus = provider.second->setCallback(nullptr); 2200 ASSERT_TRUE(returnStatus.isOk()); 2201 ASSERT_EQ(Status::OK, returnStatus); 2202 } 2203} 2204 2205// Check dump functionality. 2206TEST_F(CameraHidlTest, dumpState) { 2207 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2208 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2209 provider.second); 2210 Return<void> ret; 2211 2212 for (const auto& name : cameraDeviceNames) { 2213 if (getCameraDeviceVersion(name, provider.first) == 2214 CAMERA_DEVICE_API_VERSION_3_2) { 2215 ::android::sp<ICameraDevice> device3_2; 2216 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2217 ret = provider.second->getCameraDeviceInterface_V3_x( 2218 name, 2219 [&](auto status, const auto& device) { 2220 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 2221 (int)status); 2222 ASSERT_EQ(Status::OK, status); 2223 ASSERT_NE(device, nullptr); 2224 device3_2 = device; 2225 }); 2226 ASSERT_TRUE(ret.isOk()); 2227 2228 native_handle_t* raw_handle = native_handle_create(1, 0); 2229 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2230 ASSERT_GE(raw_handle->data[0], 0); 2231 hidl_handle handle = raw_handle; 2232 ret= device3_2->dumpState(handle); 2233 ASSERT_TRUE(ret.isOk()); 2234 close(raw_handle->data[0]); 2235 native_handle_delete(raw_handle); 2236 } else if (getCameraDeviceVersion(name, provider.first) == 2237 CAMERA_DEVICE_API_VERSION_1_0) { 2238 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2239 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2240 ret = provider.second->getCameraDeviceInterface_V1_x( 2241 name, 2242 [&](auto status, const auto& device) { 2243 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 2244 (int)status); 2245 ASSERT_EQ(Status::OK, status); 2246 ASSERT_NE(device, nullptr); 2247 device1 = device; 2248 }); 2249 ASSERT_TRUE(ret.isOk()); 2250 2251 native_handle_t* raw_handle = native_handle_create(1, 0); 2252 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2253 ASSERT_GE(raw_handle->data[0], 0); 2254 hidl_handle handle = raw_handle; 2255 Return<Status> returnStatus = device1->dumpState(handle); 2256 ASSERT_TRUE(returnStatus.isOk()); 2257 ASSERT_EQ(Status::OK, returnStatus); 2258 close(raw_handle->data[0]); 2259 native_handle_delete(raw_handle); 2260 } 2261 } 2262 } 2263} 2264 2265// Open, dumpStates, then close 2266TEST_F(CameraHidlTest, openClose) { 2267 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2268 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2269 provider.second); 2270 Return<void> ret; 2271 2272 for (const auto& name : cameraDeviceNames) { 2273 if (getCameraDeviceVersion(name, provider.first) == 2274 CAMERA_DEVICE_API_VERSION_3_2) { 2275 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; 2276 ALOGI("openClose: Testing camera device %s", name.c_str()); 2277 ret = provider.second->getCameraDeviceInterface_V3_x( 2278 name, 2279 [&](auto status, const auto& device) { 2280 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 2281 (int)status); 2282 ASSERT_EQ(Status::OK, status); 2283 ASSERT_NE(device, nullptr); 2284 device3_2 = device; 2285 }); 2286 ASSERT_TRUE(ret.isOk()); 2287 2288 sp<EmptyDeviceCb> cb = new EmptyDeviceCb; 2289 sp<ICameraDeviceSession> session; 2290 ret = device3_2->open( 2291 cb, 2292 [&](auto status, const auto& newSession) { 2293 ALOGI("device::open returns status:%d", (int)status); 2294 ASSERT_EQ(Status::OK, status); 2295 ASSERT_NE(newSession, nullptr); 2296 session = newSession; 2297 }); 2298 ASSERT_TRUE(ret.isOk()); 2299 2300 native_handle_t* raw_handle = native_handle_create(1, 0); 2301 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2302 ASSERT_GE(raw_handle->data[0], 0); 2303 hidl_handle handle = raw_handle; 2304 ret = device3_2->dumpState(handle); 2305 ASSERT_TRUE(ret.isOk()); 2306 close(raw_handle->data[0]); 2307 native_handle_delete(raw_handle); 2308 2309 ret = session->close(); 2310 ASSERT_TRUE(ret.isOk()); 2311 // TODO: test all session API calls return INTERNAL_ERROR after close 2312 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope 2313 } else if (getCameraDeviceVersion(name, provider.first) == 2314 CAMERA_DEVICE_API_VERSION_1_0) { 2315 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2316 openCameraDevice(name, provider.second, &device1 /*out*/); 2317 ASSERT_NE(nullptr, device1.get()); 2318 2319 native_handle_t* raw_handle = native_handle_create(1, 0); 2320 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2321 ASSERT_GE(raw_handle->data[0], 0); 2322 hidl_handle handle = raw_handle; 2323 Return<Status> returnStatus = device1->dumpState(handle); 2324 ASSERT_TRUE(returnStatus.isOk()); 2325 ASSERT_EQ(Status::OK, returnStatus); 2326 close(raw_handle->data[0]); 2327 native_handle_delete(raw_handle); 2328 2329 ret = device1->close(); 2330 ASSERT_TRUE(ret.isOk()); 2331 } 2332 } 2333 } 2334} 2335 2336// Check whether all common default request settings can be sucessfully 2337// constructed. 2338TEST_F(CameraHidlTest, constructDefaultRequestSettings) { 2339 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2340 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2341 provider.second); 2342 2343 for (const auto& name : cameraDeviceNames) { 2344 if (getCameraDeviceVersion(name, provider.first) == 2345 CAMERA_DEVICE_API_VERSION_3_2) { 2346 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_2; 2347 Return<void> ret; 2348 ALOGI("constructDefaultRequestSettings: Testing camera device %s", 2349 name.c_str()); 2350 ret = provider.second->getCameraDeviceInterface_V3_x( 2351 name, 2352 [&](auto status, const auto& device) { 2353 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 2354 (int)status); 2355 ASSERT_EQ(Status::OK, status); 2356 ASSERT_NE(device, nullptr); 2357 device3_2 = device; 2358 }); 2359 ASSERT_TRUE(ret.isOk()); 2360 2361 sp<EmptyDeviceCb> cb = new EmptyDeviceCb; 2362 sp<ICameraDeviceSession> session; 2363 ret = device3_2->open( 2364 cb, 2365 [&](auto status, const auto& newSession) { 2366 ALOGI("device::open returns status:%d", (int)status); 2367 ASSERT_EQ(Status::OK, status); 2368 ASSERT_NE(newSession, nullptr); 2369 session = newSession; 2370 }); 2371 ASSERT_TRUE(ret.isOk()); 2372 2373 for (uint32_t t = (uint32_t) RequestTemplate::PREVIEW; 2374 t <= (uint32_t) RequestTemplate::MANUAL; t++) { 2375 RequestTemplate reqTemplate = (RequestTemplate) t; 2376 ret = session->constructDefaultRequestSettings( 2377 reqTemplate, 2378 [&](auto status, const auto& req) { 2379 ALOGI("constructDefaultRequestSettings returns status:%d", 2380 (int)status); 2381 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG || 2382 reqTemplate == RequestTemplate::MANUAL) { 2383 // optional templates 2384 ASSERT_TRUE((status == Status::OK) || 2385 (status == Status::ILLEGAL_ARGUMENT)); 2386 } else { 2387 ASSERT_EQ(Status::OK, status); 2388 } 2389 2390 if (status == Status::OK) { 2391 const camera_metadata_t* metadata = 2392 (camera_metadata_t*) req.data(); 2393 size_t expectedSize = req.size(); 2394 int result = validate_camera_metadata_structure( 2395 metadata, &expectedSize); 2396 ASSERT_TRUE((result == 0) || 2397 (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 2398 size_t entryCount = 2399 get_camera_metadata_entry_count(metadata); 2400 // TODO: we can do better than 0 here. Need to check how many required 2401 // request keys we've defined for each template 2402 ASSERT_GT(entryCount, 0u); 2403 ALOGI("template %u metadata entry count is %zu", 2404 t, entryCount); 2405 } else { 2406 ASSERT_EQ(0u, req.size()); 2407 } 2408 }); 2409 ASSERT_TRUE(ret.isOk()); 2410 } 2411 ret = session->close(); 2412 ASSERT_TRUE(ret.isOk()); 2413 } 2414 } 2415 } 2416} 2417 2418// Verify that all supported stream formats and sizes can be configured 2419// successfully. 2420TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { 2421 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2422 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2423 provider.second); 2424 std::vector<AvailableStream> outputStreams; 2425 2426 for (const auto& name : cameraDeviceNames) { 2427 if (getCameraDeviceVersion(name, provider.first) == 2428 CAMERA_DEVICE_API_VERSION_3_2) { 2429 camera_metadata_t *staticMeta; 2430 Return<void> ret; 2431 sp<ICameraDeviceSession> session; 2432 openEmptyDeviceSession(name, provider.second, &session /*out*/, 2433 &staticMeta /*out*/); 2434 2435 outputStreams.clear(); 2436 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2437 outputStreams)); 2438 ASSERT_NE(0u, outputStreams.size()); 2439 2440 int32_t streamId = 0; 2441 for (auto &it : outputStreams) { 2442 Stream stream = {streamId, StreamType::OUTPUT, 2443 static_cast<uint32_t> (it.width), 2444 static_cast<uint32_t> (it.height), 2445 static_cast<PixelFormat> (it.format), 0, 0, 2446 StreamRotation::ROTATION_0}; 2447 ::android::hardware::hidl_vec<Stream> streams = {stream}; 2448 StreamConfiguration config = {streams, 2449 StreamConfigurationMode::NORMAL_MODE}; 2450 ret = session->configureStreams(config, [streamId] (Status s, 2451 HalStreamConfiguration halConfig) { 2452 ASSERT_EQ(Status::OK, s); 2453 ASSERT_EQ(1u, halConfig.streams.size()); 2454 ASSERT_EQ(halConfig.streams[0].id, streamId); 2455 }); 2456 ASSERT_TRUE(ret.isOk()); 2457 streamId++; 2458 } 2459 2460 free_camera_metadata(staticMeta); 2461 ret = session->close(); 2462 ASSERT_TRUE(ret.isOk()); 2463 } 2464 } 2465 } 2466} 2467 2468// Check for correct handling of invalid/incorrect configuration parameters. 2469TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { 2470 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2471 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2472 provider.second); 2473 std::vector<AvailableStream> outputStreams; 2474 2475 for (const auto& name : cameraDeviceNames) { 2476 if (getCameraDeviceVersion(name, provider.first) == 2477 CAMERA_DEVICE_API_VERSION_3_2) { 2478 camera_metadata_t *staticMeta; 2479 Return<void> ret; 2480 sp<ICameraDeviceSession> session; 2481 openEmptyDeviceSession(name, provider.second, &session /*out*/, 2482 &staticMeta /*out*/); 2483 2484 outputStreams.clear(); 2485 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2486 outputStreams)); 2487 ASSERT_NE(0u, outputStreams.size()); 2488 2489 int32_t streamId = 0; 2490 Stream stream = {streamId++, StreamType::OUTPUT, 2491 static_cast<uint32_t> (0), 2492 static_cast<uint32_t> (0), 2493 static_cast<PixelFormat> (outputStreams[0].format), 2494 0, 0, StreamRotation::ROTATION_0}; 2495 ::android::hardware::hidl_vec<Stream> streams = {stream}; 2496 StreamConfiguration config = {streams, 2497 StreamConfigurationMode::NORMAL_MODE}; 2498 ret = session->configureStreams(config, [] (Status s, 2499 HalStreamConfiguration) { 2500 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2501 (Status::INTERNAL_ERROR == s)); 2502 }); 2503 ASSERT_TRUE(ret.isOk()); 2504 2505 stream = {streamId++, StreamType::OUTPUT, 2506 static_cast<uint32_t> (UINT32_MAX), 2507 static_cast<uint32_t> (UINT32_MAX), 2508 static_cast<PixelFormat> (outputStreams[0].format), 2509 0, 0, StreamRotation::ROTATION_0}; 2510 streams[0] = stream; 2511 config = {streams, 2512 StreamConfigurationMode::NORMAL_MODE}; 2513 ret = session->configureStreams(config, [] (Status s, 2514 HalStreamConfiguration) { 2515 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2516 }); 2517 ASSERT_TRUE(ret.isOk()); 2518 2519 for (auto &it : outputStreams) { 2520 stream = {streamId++, StreamType::OUTPUT, 2521 static_cast<uint32_t> (it.width), 2522 static_cast<uint32_t> (it.height), 2523 static_cast<PixelFormat> (UINT32_MAX), 2524 0, 0, StreamRotation::ROTATION_0}; 2525 streams[0] = stream; 2526 config = {streams, 2527 StreamConfigurationMode::NORMAL_MODE}; 2528 ret = session->configureStreams(config, [] (Status s, 2529 HalStreamConfiguration) { 2530 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2531 }); 2532 ASSERT_TRUE(ret.isOk()); 2533 2534 stream = {streamId++, StreamType::OUTPUT, 2535 static_cast<uint32_t> (it.width), 2536 static_cast<uint32_t> (it.height), 2537 static_cast<PixelFormat> (it.format), 2538 0, 0, static_cast<StreamRotation> (UINT32_MAX)}; 2539 streams[0] = stream; 2540 config = {streams, 2541 StreamConfigurationMode::NORMAL_MODE}; 2542 ret = session->configureStreams(config, [] (Status s, 2543 HalStreamConfiguration) { 2544 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2545 }); 2546 ASSERT_TRUE(ret.isOk()); 2547 } 2548 2549 free_camera_metadata(staticMeta); 2550 ret = session->close(); 2551 ASSERT_TRUE(ret.isOk()); 2552 } 2553 } 2554 } 2555} 2556 2557// Check whether all supported ZSL output stream combinations can be 2558// configured successfully. 2559TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { 2560 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2561 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2562 provider.second); 2563 std::vector<AvailableStream> inputStreams; 2564 std::vector<AvailableZSLInputOutput> inputOutputMap; 2565 2566 for (const auto& name : cameraDeviceNames) { 2567 if (getCameraDeviceVersion(name, provider.first) == 2568 CAMERA_DEVICE_API_VERSION_3_2) { 2569 camera_metadata_t *staticMeta; 2570 Return<void> ret; 2571 sp<ICameraDeviceSession> session; 2572 openEmptyDeviceSession(name, provider.second, &session /*out*/, 2573 &staticMeta /*out*/); 2574 2575 Status rc = isZSLModeAvailable(staticMeta); 2576 if (Status::METHOD_NOT_SUPPORTED == rc) { 2577 ret = session->close(); 2578 ASSERT_TRUE(ret.isOk()); 2579 continue; 2580 } 2581 ASSERT_EQ(Status::OK, rc); 2582 2583 inputStreams.clear(); 2584 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2585 inputStreams)); 2586 ASSERT_NE(0u, inputStreams.size()); 2587 2588 inputOutputMap.clear(); 2589 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, 2590 inputOutputMap)); 2591 ASSERT_NE(0u, inputOutputMap.size()); 2592 2593 int32_t streamId = 0; 2594 for (auto &inputIter : inputOutputMap) { 2595 AvailableStream input; 2596 ASSERT_EQ(Status::OK, 2597 findLargestSize(inputStreams, inputIter.inputFormat, input)); 2598 ASSERT_NE(0u, inputStreams.size()); 2599 2600 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, 2601 inputIter.outputFormat}; 2602 std::vector<AvailableStream> outputStreams; 2603 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2604 outputStreams, &outputThreshold)); 2605 for (auto &outputIter : outputStreams) { 2606 Stream zslStream = {streamId++, StreamType::OUTPUT, 2607 static_cast<uint32_t> (input.width), 2608 static_cast<uint32_t> (input.height), 2609 static_cast<PixelFormat> (input.format), 2610 GRALLOC_USAGE_HW_CAMERA_ZSL, 0, 2611 StreamRotation::ROTATION_0}; 2612 Stream inputStream = {streamId++, StreamType::INPUT, 2613 static_cast<uint32_t> (input.width), 2614 static_cast<uint32_t> (input.height), 2615 static_cast<PixelFormat> (input.format), 0, 0, 2616 StreamRotation::ROTATION_0}; 2617 Stream outputStream = {streamId++, StreamType::OUTPUT, 2618 static_cast<uint32_t> (outputIter.width), 2619 static_cast<uint32_t> (outputIter.height), 2620 static_cast<PixelFormat> (outputIter.format), 0, 0, 2621 StreamRotation::ROTATION_0}; 2622 2623 ::android::hardware::hidl_vec<Stream> streams = { 2624 inputStream, zslStream, outputStream}; 2625 StreamConfiguration config = {streams, 2626 StreamConfigurationMode::NORMAL_MODE}; 2627 ret = session->configureStreams(config, [] (Status s, 2628 HalStreamConfiguration halConfig) { 2629 ASSERT_EQ(Status::OK, s); 2630 ASSERT_EQ(3u, halConfig.streams.size()); 2631 }); 2632 ASSERT_TRUE(ret.isOk()); 2633 } 2634 } 2635 2636 free_camera_metadata(staticMeta); 2637 ret = session->close(); 2638 ASSERT_TRUE(ret.isOk()); 2639 } 2640 } 2641 } 2642} 2643 2644// Verify that all supported preview + still capture stream combinations 2645// can be configured successfully. 2646TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { 2647 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2648 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2649 provider.second); 2650 std::vector<AvailableStream> outputBlobStreams; 2651 std::vector<AvailableStream> outputPreviewStreams; 2652 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 2653 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2654 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX, 2655 static_cast<int32_t>(PixelFormat::BLOB)}; 2656 2657 for (const auto& name : cameraDeviceNames) { 2658 if (getCameraDeviceVersion(name, provider.first) == 2659 CAMERA_DEVICE_API_VERSION_3_2) { 2660 camera_metadata_t *staticMeta; 2661 Return<void> ret; 2662 sp<ICameraDeviceSession> session; 2663 openEmptyDeviceSession(name, provider.second, &session /*out*/, 2664 &staticMeta /*out*/); 2665 2666 outputBlobStreams.clear(); 2667 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2668 outputBlobStreams, &blobThreshold)); 2669 ASSERT_NE(0u, outputBlobStreams.size()); 2670 2671 outputPreviewStreams.clear(); 2672 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2673 outputPreviewStreams, &previewThreshold)); 2674 ASSERT_NE(0u, outputPreviewStreams.size()); 2675 2676 int32_t streamId = 0; 2677 for (auto &blobIter : outputBlobStreams) { 2678 for (auto &previewIter : outputPreviewStreams) { 2679 Stream previewStream = {streamId++, StreamType::OUTPUT, 2680 static_cast<uint32_t> (previewIter.width), 2681 static_cast<uint32_t> (previewIter.height), 2682 static_cast<PixelFormat> (previewIter.format), 0, 0, 2683 StreamRotation::ROTATION_0}; 2684 Stream blobStream = {streamId++, StreamType::OUTPUT, 2685 static_cast<uint32_t> (blobIter.width), 2686 static_cast<uint32_t> (blobIter.height), 2687 static_cast<PixelFormat> (blobIter.format), 0, 0, 2688 StreamRotation::ROTATION_0}; 2689 ::android::hardware::hidl_vec<Stream> streams = { 2690 previewStream, blobStream}; 2691 StreamConfiguration config = {streams, 2692 StreamConfigurationMode::NORMAL_MODE}; 2693 ret = session->configureStreams(config, [] (Status s, 2694 HalStreamConfiguration halConfig) { 2695 ASSERT_EQ(Status::OK, s); 2696 ASSERT_EQ(2u, halConfig.streams.size()); 2697 }); 2698 ASSERT_TRUE(ret.isOk()); 2699 } 2700 } 2701 2702 free_camera_metadata(staticMeta); 2703 ret = session->close(); 2704 ASSERT_TRUE(ret.isOk()); 2705 } 2706 } 2707 } 2708} 2709 2710// In case constrained mode is supported, test whether it can be 2711// configured. Additionally check for common invalid inputs when 2712// using this mode. 2713TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { 2714 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2715 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2716 provider.second); 2717 2718 for (const auto& name : cameraDeviceNames) { 2719 if (getCameraDeviceVersion(name, provider.first) == 2720 CAMERA_DEVICE_API_VERSION_3_2) { 2721 camera_metadata_t *staticMeta; 2722 Return<void> ret; 2723 sp<ICameraDeviceSession> session; 2724 openEmptyDeviceSession(name, provider.second, &session /*out*/, 2725 &staticMeta /*out*/); 2726 2727 Status rc = isConstrainedModeAvailable(staticMeta); 2728 if (Status::METHOD_NOT_SUPPORTED == rc) { 2729 ret = session->close(); 2730 ASSERT_TRUE(ret.isOk()); 2731 continue; 2732 } 2733 ASSERT_EQ(Status::OK, rc); 2734 2735 AvailableStream hfrStream; 2736 rc = pickConstrainedModeSize(staticMeta, hfrStream); 2737 ASSERT_EQ(Status::OK, rc); 2738 2739 int32_t streamId = 0; 2740 Stream stream = {streamId, StreamType::OUTPUT, 2741 static_cast<uint32_t> (hfrStream.width), 2742 static_cast<uint32_t> (hfrStream.height), 2743 static_cast<PixelFormat> (hfrStream.format), 0, 0, 2744 StreamRotation::ROTATION_0}; 2745 ::android::hardware::hidl_vec<Stream> streams = {stream}; 2746 StreamConfiguration config = {streams, 2747 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2748 ret = session->configureStreams(config, [streamId] (Status s, 2749 HalStreamConfiguration halConfig) { 2750 ASSERT_EQ(Status::OK, s); 2751 ASSERT_EQ(1u, halConfig.streams.size()); 2752 ASSERT_EQ(halConfig.streams[0].id, streamId); 2753 }); 2754 ASSERT_TRUE(ret.isOk()); 2755 2756 stream = {streamId++, StreamType::OUTPUT, 2757 static_cast<uint32_t> (0), 2758 static_cast<uint32_t> (0), 2759 static_cast<PixelFormat> (hfrStream.format), 0, 0, 2760 StreamRotation::ROTATION_0}; 2761 streams[0] = stream; 2762 config = {streams, 2763 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2764 ret = session->configureStreams(config, [] (Status s, 2765 HalStreamConfiguration) { 2766 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2767 (Status::INTERNAL_ERROR == s)); 2768 }); 2769 ASSERT_TRUE(ret.isOk()); 2770 2771 stream = {streamId++, StreamType::OUTPUT, 2772 static_cast<uint32_t> (UINT32_MAX), 2773 static_cast<uint32_t> (UINT32_MAX), 2774 static_cast<PixelFormat> (hfrStream.format), 0, 0, 2775 StreamRotation::ROTATION_0}; 2776 streams[0] = stream; 2777 config = {streams, 2778 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2779 ret = session->configureStreams(config, [] (Status s, 2780 HalStreamConfiguration) { 2781 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2782 }); 2783 ASSERT_TRUE(ret.isOk()); 2784 2785 stream = {streamId++, StreamType::OUTPUT, 2786 static_cast<uint32_t> (hfrStream.width), 2787 static_cast<uint32_t> (hfrStream.height), 2788 static_cast<PixelFormat> (UINT32_MAX), 0, 0, 2789 StreamRotation::ROTATION_0}; 2790 streams[0] = stream; 2791 config = {streams, 2792 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2793 ret = session->configureStreams(config, [] (Status s, 2794 HalStreamConfiguration) { 2795 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2796 }); 2797 ASSERT_TRUE(ret.isOk()); 2798 2799 free_camera_metadata(staticMeta); 2800 ret = session->close(); 2801 ASSERT_TRUE(ret.isOk()); 2802 } 2803 } 2804 } 2805} 2806 2807// Verify that all supported video + snapshot stream combinations can 2808// be configured successfully. 2809TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { 2810 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2811 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2812 provider.second); 2813 std::vector<AvailableStream> outputBlobStreams; 2814 std::vector<AvailableStream> outputVideoStreams; 2815 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight, 2816 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2817 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight, 2818 static_cast<int32_t>(PixelFormat::BLOB)}; 2819 2820 for (const auto& name : cameraDeviceNames) { 2821 if (getCameraDeviceVersion(name, provider.first) == 2822 CAMERA_DEVICE_API_VERSION_3_2) { 2823 camera_metadata_t *staticMeta; 2824 Return<void> ret; 2825 sp<ICameraDeviceSession> session; 2826 openEmptyDeviceSession(name, provider.second, &session /*out*/, 2827 &staticMeta /*out*/); 2828 2829 outputBlobStreams.clear(); 2830 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2831 outputBlobStreams, &blobThreshold)); 2832 ASSERT_NE(0u, outputBlobStreams.size()); 2833 2834 outputVideoStreams.clear(); 2835 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, 2836 outputVideoStreams, &videoThreshold)); 2837 ASSERT_NE(0u, outputVideoStreams.size()); 2838 2839 int32_t streamId = 0; 2840 for (auto &blobIter : outputBlobStreams) { 2841 for (auto &videoIter : outputVideoStreams) { 2842 Stream videoStream = {streamId++, StreamType::OUTPUT, 2843 static_cast<uint32_t> (videoIter.width), 2844 static_cast<uint32_t> (videoIter.height), 2845 static_cast<PixelFormat> (videoIter.format), 2846 0, 0, StreamRotation::ROTATION_0}; 2847 Stream blobStream = {streamId++, StreamType::OUTPUT, 2848 static_cast<uint32_t> (blobIter.width), 2849 static_cast<uint32_t> (blobIter.height), 2850 static_cast<PixelFormat> (blobIter.format), 2851 GRALLOC_USAGE_HW_VIDEO_ENCODER, 0, 2852 StreamRotation::ROTATION_0}; 2853 ::android::hardware::hidl_vec<Stream> streams = { 2854 videoStream, blobStream}; 2855 StreamConfiguration config = {streams, 2856 StreamConfigurationMode::NORMAL_MODE}; 2857 ret = session->configureStreams(config, [] ( 2858 Status s, HalStreamConfiguration halConfig) { 2859 ASSERT_EQ(Status::OK, s); 2860 ASSERT_EQ(2u, halConfig.streams.size()); 2861 }); 2862 ASSERT_TRUE(ret.isOk()); 2863 } 2864 } 2865 2866 free_camera_metadata(staticMeta); 2867 ret = session->close(); 2868 ASSERT_TRUE(ret.isOk()); 2869 } 2870 } 2871 } 2872} 2873 2874// Generate and verify a camera capture request 2875TEST_F(CameraHidlTest, processCaptureRequestPreview) { 2876 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 2877 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 2878 provider.second); 2879 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 2880 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2881 uint64_t bufferId = 1; 2882 uint32_t frameNumber = 1; 2883 ::android::hardware::hidl_vec<uint8_t> settings; 2884 2885 for (const auto& name : cameraDeviceNames) { 2886 if (getCameraDeviceVersion(name, provider.first) == 2887 CAMERA_DEVICE_API_VERSION_3_2) { 2888 Stream previewStream; 2889 HalStreamConfiguration halStreamConfig; 2890 sp<ICameraDeviceSession> session; 2891 bool supportsPartialResults = false; 2892 uint32_t partialResultCount = 0; 2893 configurePreviewStream(name, provider.second, &previewThreshold, 2894 &session /*out*/, &previewStream /*out*/, 2895 &halStreamConfig /*out*/, &supportsPartialResults /*out*/, 2896 &partialResultCount/*out*/); 2897 2898 std::shared_ptr<ResultMetadataQueue> resultQueue; 2899 auto resultQueueRet = session->getCaptureResultMetadataQueue( 2900 [&resultQueue](const auto& descriptor) { 2901 resultQueue = std::make_shared<ResultMetadataQueue>( 2902 descriptor); 2903 if (!resultQueue->isValid() || 2904 resultQueue->availableToWrite() <= 0) { 2905 ALOGE("%s: HAL returns empty result metadata fmq," 2906 " not use it", __func__); 2907 resultQueue = nullptr; 2908 // Don't use the queue onwards. 2909 } 2910 }); 2911 ASSERT_TRUE(resultQueueRet.isOk()); 2912 ASSERT_NE(nullptr, resultQueue); 2913 2914 InFlightRequest inflightReq = {1, false, supportsPartialResults, 2915 partialResultCount, resultQueue}; 2916 2917 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 2918 Return<void> ret; 2919 ret = session->constructDefaultRequestSettings(reqTemplate, 2920 [&](auto status, const auto& req) { 2921 ASSERT_EQ(Status::OK, status); 2922 settings = req; }); 2923 ASSERT_TRUE(ret.isOk()); 2924 2925 sp<GraphicBuffer> gb = new GraphicBuffer( 2926 previewStream.width, previewStream.height, 2927 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 2928 1, android_convertGralloc1To0Usage( 2929 halStreamConfig.streams[0].producerUsage, 2930 halStreamConfig.streams[0].consumerUsage)); 2931 ASSERT_NE(nullptr, gb.get()); 2932 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 2933 bufferId, hidl_handle(gb->getNativeBuffer()->handle), 2934 BufferStatus::OK, nullptr, nullptr}; 2935 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = { 2936 outputBuffer}; 2937 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, 2938 BufferStatus::ERROR, nullptr, nullptr}; 2939 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, 2940 settings, emptyInputBuffer, outputBuffers}; 2941 2942 { 2943 std::unique_lock<std::mutex> l(mLock); 2944 mInflightMap.clear(); 2945 mInflightMap.add(frameNumber, &inflightReq); 2946 } 2947 2948 Status status = Status::INTERNAL_ERROR; 2949 uint32_t numRequestProcessed = 0; 2950 hidl_vec<BufferCache> cachesToRemove; 2951 Return<void> returnStatus = session->processCaptureRequest( 2952 {request}, 2953 cachesToRemove, 2954 [&status, &numRequestProcessed] (auto s, uint32_t n) { 2955 status = s; 2956 numRequestProcessed = n; 2957 }); 2958 ASSERT_TRUE(returnStatus.isOk()); 2959 ASSERT_EQ(Status::OK, status); 2960 ASSERT_EQ(numRequestProcessed, 1u); 2961 2962 { 2963 std::unique_lock<std::mutex> l(mLock); 2964 while (!inflightReq.errorCodeValid && 2965 ((0 < inflightReq.numBuffersLeft) || 2966 (!inflightReq.haveResultMetadata))) { 2967 auto timeout = std::chrono::system_clock::now() + 2968 std::chrono::seconds(kStreamBufferTimeoutSec); 2969 ASSERT_NE(std::cv_status::timeout, 2970 mResultCondition.wait_until(l, timeout)); 2971 } 2972 2973 ASSERT_FALSE(inflightReq.errorCodeValid); 2974 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 2975 ASSERT_EQ(previewStream.id, 2976 inflightReq.resultOutputBuffers[0].streamId); 2977 2978 request.frameNumber++; 2979 //Empty settings should be supported after the first call 2980 //for repeating requests. 2981 request.settings.setToExternal(nullptr, 0, true); 2982 mInflightMap.clear(); 2983 inflightReq = {1, false, supportsPartialResults, 2984 partialResultCount, resultQueue}; 2985 mInflightMap.add(request.frameNumber, &inflightReq); 2986 } 2987 2988 returnStatus = session->processCaptureRequest( 2989 {request}, 2990 cachesToRemove, 2991 [&status, &numRequestProcessed] (auto s, uint32_t n) { 2992 status = s; 2993 numRequestProcessed = n; 2994 }); 2995 ASSERT_TRUE(returnStatus.isOk()); 2996 ASSERT_EQ(Status::OK, status); 2997 ASSERT_EQ(numRequestProcessed, 1u); 2998 2999 { 3000 std::unique_lock<std::mutex> l(mLock); 3001 while (!inflightReq.errorCodeValid && 3002 ((0 < inflightReq.numBuffersLeft) || 3003 (!inflightReq.haveResultMetadata))) { 3004 auto timeout = std::chrono::system_clock::now() + 3005 std::chrono::seconds(kStreamBufferTimeoutSec); 3006 ASSERT_NE(std::cv_status::timeout, 3007 mResultCondition.wait_until(l, timeout)); 3008 } 3009 3010 ASSERT_FALSE(inflightReq.errorCodeValid); 3011 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3012 ASSERT_EQ(previewStream.id, 3013 inflightReq.resultOutputBuffers[0].streamId); 3014 } 3015 3016 ret = session->close(); 3017 ASSERT_TRUE(ret.isOk()); 3018 } 3019 } 3020 } 3021} 3022 3023// Test whether an incorrect capture request with missing settings will 3024// be reported correctly. 3025TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) { 3026 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 3027 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 3028 provider.second); 3029 std::vector<AvailableStream> outputPreviewStreams; 3030 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3031 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3032 uint64_t bufferId = 1; 3033 uint32_t frameNumber = 1; 3034 ::android::hardware::hidl_vec<uint8_t> settings; 3035 3036 for (const auto& name : cameraDeviceNames) { 3037 if (getCameraDeviceVersion(name, provider.first) == 3038 CAMERA_DEVICE_API_VERSION_3_2) { 3039 Stream previewStream; 3040 HalStreamConfiguration halStreamConfig; 3041 sp<ICameraDeviceSession> session; 3042 bool supportsPartialResults = false; 3043 uint32_t partialResultCount = 0; 3044 configurePreviewStream(name, provider.second, &previewThreshold, 3045 &session /*out*/, &previewStream /*out*/, 3046 &halStreamConfig /*out*/, &supportsPartialResults /*out*/, 3047 &partialResultCount /*out*/); 3048 3049 sp<GraphicBuffer> gb = new GraphicBuffer( 3050 previewStream.width, previewStream.height, 3051 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 3052 1, android_convertGralloc1To0Usage( 3053 halStreamConfig.streams[0].producerUsage, 3054 halStreamConfig.streams[0].consumerUsage)); 3055 3056 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3057 bufferId, hidl_handle(gb->getNativeBuffer()->handle), 3058 BufferStatus::OK, nullptr, nullptr}; 3059 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = { 3060 outputBuffer}; 3061 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, 3062 BufferStatus::ERROR, nullptr, nullptr}; 3063 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3064 emptyInputBuffer, outputBuffers}; 3065 3066 //Settings were not correctly initialized, we should fail here 3067 Status status = Status::OK; 3068 uint32_t numRequestProcessed = 0; 3069 hidl_vec<BufferCache> cachesToRemove; 3070 Return<void> ret = session->processCaptureRequest( 3071 {request}, 3072 cachesToRemove, 3073 [&status, &numRequestProcessed] (auto s, uint32_t n) { 3074 status = s; 3075 numRequestProcessed = n; 3076 }); 3077 ASSERT_TRUE(ret.isOk()); 3078 ASSERT_EQ(Status::INTERNAL_ERROR, status); 3079 ASSERT_EQ(numRequestProcessed, 0u); 3080 3081 ret = session->close(); 3082 ASSERT_TRUE(ret.isOk()); 3083 } 3084 } 3085 } 3086} 3087 3088// Check whether an invalid capture request with missing output buffers 3089// will be reported correctly. 3090TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) { 3091 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 3092 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 3093 provider.second); 3094 std::vector<AvailableStream> outputBlobStreams; 3095 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3096 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3097 uint32_t frameNumber = 1; 3098 ::android::hardware::hidl_vec<uint8_t> settings; 3099 3100 for (const auto& name : cameraDeviceNames) { 3101 if (getCameraDeviceVersion(name, provider.first) == 3102 CAMERA_DEVICE_API_VERSION_3_2) { 3103 Stream previewStream; 3104 HalStreamConfiguration halStreamConfig; 3105 sp<ICameraDeviceSession> session; 3106 bool supportsPartialResults = false; 3107 uint32_t partialResultCount = 0; 3108 configurePreviewStream(name, provider.second, &previewThreshold, 3109 &session /*out*/, &previewStream /*out*/, 3110 &halStreamConfig /*out*/, &supportsPartialResults/*out*/, 3111 &partialResultCount /*out*/); 3112 3113 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3114 Return<void> ret; 3115 ret = session->constructDefaultRequestSettings(reqTemplate, 3116 [&](auto status, const auto& req) { 3117 ASSERT_EQ(Status::OK, status); 3118 settings = req; }); 3119 ASSERT_TRUE(ret.isOk()); 3120 3121 ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers; 3122 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, 3123 BufferStatus::ERROR, nullptr, nullptr}; 3124 CaptureRequest request = {frameNumber, 0/* fmqSettingsSize */, 3125 settings, emptyInputBuffer, emptyOutputBuffers}; 3126 3127 //Output buffers are missing, we should fail here 3128 Status status = Status::OK; 3129 uint32_t numRequestProcessed = 0; 3130 hidl_vec<BufferCache> cachesToRemove; 3131 ret = session->processCaptureRequest( 3132 {request}, 3133 cachesToRemove, 3134 [&status, &numRequestProcessed] (auto s, uint32_t n) { 3135 status = s; 3136 numRequestProcessed = n; 3137 }); 3138 ASSERT_TRUE(ret.isOk()); 3139 ASSERT_EQ(Status::INTERNAL_ERROR, status); 3140 ASSERT_EQ(numRequestProcessed, 0u); 3141 3142 ret = session->close(); 3143 ASSERT_TRUE(ret.isOk()); 3144 } 3145 } 3146 } 3147} 3148 3149// Generate, trigger and flush a preview request 3150TEST_F(CameraHidlTest, flushPreviewRequest) { 3151 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 3152 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 3153 provider.second); 3154 std::vector<AvailableStream> outputPreviewStreams; 3155 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3156 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3157 uint64_t bufferId = 1; 3158 uint32_t frameNumber = 1; 3159 ::android::hardware::hidl_vec<uint8_t> settings; 3160 3161 for (const auto& name : cameraDeviceNames) { 3162 if (getCameraDeviceVersion(name, provider.first) == 3163 CAMERA_DEVICE_API_VERSION_3_2) { 3164 Stream previewStream; 3165 HalStreamConfiguration halStreamConfig; 3166 sp<ICameraDeviceSession> session; 3167 bool supportsPartialResults = false; 3168 uint32_t partialResultCount = 0; 3169 configurePreviewStream(name, provider.second, &previewThreshold, 3170 &session /*out*/, &previewStream /*out*/, 3171 &halStreamConfig /*out*/, &supportsPartialResults /*out*/, 3172 &partialResultCount /*out*/); 3173 3174 std::shared_ptr<ResultMetadataQueue> resultQueue; 3175 auto resultQueueRet = session->getCaptureResultMetadataQueue( 3176 [&resultQueue](const auto& descriptor) { 3177 resultQueue = std::make_shared<ResultMetadataQueue>( 3178 descriptor); 3179 if (!resultQueue->isValid() || 3180 resultQueue->availableToWrite() <= 0) { 3181 ALOGE("%s: HAL returns empty result metadata fmq," 3182 " not use it", __func__); 3183 resultQueue = nullptr; 3184 // Don't use the queue onwards. 3185 } 3186 }); 3187 ASSERT_TRUE(resultQueueRet.isOk()); 3188 ASSERT_NE(nullptr, resultQueue); 3189 3190 InFlightRequest inflightReq = {1, false, supportsPartialResults, 3191 partialResultCount, resultQueue}; 3192 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3193 Return<void> ret; 3194 ret = session->constructDefaultRequestSettings(reqTemplate, 3195 [&](auto status, const auto& req) { 3196 ASSERT_EQ(Status::OK, status); 3197 settings = req; }); 3198 ASSERT_TRUE(ret.isOk()); 3199 3200 sp<GraphicBuffer> gb = new GraphicBuffer( 3201 previewStream.width, previewStream.height, 3202 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 3203 1, android_convertGralloc1To0Usage( 3204 halStreamConfig.streams[0].producerUsage, 3205 halStreamConfig.streams[0].consumerUsage)); 3206 ASSERT_NE(nullptr, gb.get()); 3207 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3208 bufferId, hidl_handle(gb->getNativeBuffer()->handle), 3209 BufferStatus::OK, nullptr, nullptr}; 3210 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = { 3211 outputBuffer}; 3212 const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, 3213 BufferStatus::ERROR, nullptr, nullptr}; 3214 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, 3215 settings, emptyInputBuffer, outputBuffers}; 3216 3217 { 3218 std::unique_lock<std::mutex> l(mLock); 3219 mInflightMap.clear(); 3220 mInflightMap.add(frameNumber, &inflightReq); 3221 } 3222 3223 Status status = Status::INTERNAL_ERROR; 3224 uint32_t numRequestProcessed = 0; 3225 hidl_vec<BufferCache> cachesToRemove; 3226 ret = session->processCaptureRequest( 3227 {request}, 3228 cachesToRemove, 3229 [&status, &numRequestProcessed] (auto s, uint32_t n) { 3230 status = s; 3231 numRequestProcessed = n; 3232 }); 3233 3234 ASSERT_TRUE(ret.isOk()); 3235 ASSERT_EQ(Status::OK, status); 3236 ASSERT_EQ(numRequestProcessed, 1u); 3237 //Flush before waiting for request to complete. 3238 Return<Status> returnStatus = session->flush(); 3239 ASSERT_TRUE(returnStatus.isOk()); 3240 ASSERT_EQ(Status::OK, returnStatus); 3241 3242 { 3243 std::unique_lock<std::mutex> l(mLock); 3244 while (!inflightReq.errorCodeValid && 3245 ((0 < inflightReq.numBuffersLeft) || 3246 (!inflightReq.haveResultMetadata))) { 3247 auto timeout = std::chrono::system_clock::now() + 3248 std::chrono::seconds(kStreamBufferTimeoutSec); 3249 ASSERT_NE(std::cv_status::timeout, 3250 mResultCondition.wait_until(l, timeout)); 3251 } 3252 3253 if (!inflightReq.errorCodeValid) { 3254 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3255 ASSERT_EQ(previewStream.id, 3256 inflightReq.resultOutputBuffers[0].streamId); 3257 } else { 3258 switch (inflightReq.errorCode) { 3259 case ErrorCode::ERROR_REQUEST: 3260 case ErrorCode::ERROR_RESULT: 3261 case ErrorCode::ERROR_BUFFER: 3262 //Expected 3263 break; 3264 case ErrorCode::ERROR_DEVICE: 3265 default: 3266 FAIL() << "Unexpected error:" << static_cast<uint32_t> ( 3267 inflightReq.errorCode); 3268 } 3269 } 3270 3271 ret = session->close(); 3272 ASSERT_TRUE(ret.isOk()); 3273 } 3274 } 3275 } 3276 } 3277} 3278 3279// Verify that camera flushes correctly without any pending requests. 3280TEST_F(CameraHidlTest, flushEmpty) { 3281 for (auto provider : CameraHidlEnvironment::Instance()->mProviders) { 3282 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames( 3283 provider.second); 3284 std::vector<AvailableStream> outputPreviewStreams; 3285 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3286 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3287 3288 for (const auto& name : cameraDeviceNames) { 3289 if (getCameraDeviceVersion(name, provider.first) == 3290 CAMERA_DEVICE_API_VERSION_3_2) { 3291 Stream previewStream; 3292 HalStreamConfiguration halStreamConfig; 3293 sp<ICameraDeviceSession> session; 3294 bool supportsPartialResults = false; 3295 uint32_t partialResultCount = 0; 3296 configurePreviewStream(name, provider.second, &previewThreshold, 3297 &session /*out*/, &previewStream /*out*/, 3298 &halStreamConfig /*out*/, &supportsPartialResults /*out*/, 3299 &partialResultCount /*out*/); 3300 3301 Return<Status> returnStatus = session->flush(); 3302 ASSERT_TRUE(returnStatus.isOk()); 3303 ASSERT_EQ(Status::OK, returnStatus); 3304 3305 { 3306 std::unique_lock<std::mutex> l(mLock); 3307 auto timeout = std::chrono::system_clock::now() + 3308 std::chrono::milliseconds(kEmptyFlushTimeoutMSec); 3309 ASSERT_EQ(std::cv_status::timeout, 3310 mResultCondition.wait_until(l, timeout)); 3311 } 3312 3313 Return<void> ret = session->close(); 3314 ASSERT_TRUE(ret.isOk()); 3315 } 3316 } 3317 } 3318} 3319 3320// Retrieve all valid output stream resolutions from the camera 3321// static characteristics. 3322Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta, 3323 std::vector<AvailableStream> &outputStreams, 3324 const AvailableStream *threshold) { 3325 if (nullptr == staticMeta) { 3326 return Status::ILLEGAL_ARGUMENT; 3327 } 3328 3329 camera_metadata_ro_entry entry; 3330 int rc = find_camera_metadata_ro_entry(staticMeta, 3331 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry); 3332 if ((0 != rc) || (0 != (entry.count % 4))) { 3333 return Status::ILLEGAL_ARGUMENT; 3334 } 3335 3336 for (size_t i = 0; i < entry.count; i+=4) { 3337 if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT == 3338 entry.data.i32[i + 3]) { 3339 if(nullptr == threshold) { 3340 AvailableStream s = {entry.data.i32[i+1], 3341 entry.data.i32[i+2], entry.data.i32[i]}; 3342 outputStreams.push_back(s); 3343 } else { 3344 if ((threshold->format == entry.data.i32[i]) && 3345 (threshold->width >= entry.data.i32[i+1]) && 3346 (threshold->height >= entry.data.i32[i+2])) { 3347 AvailableStream s = {entry.data.i32[i+1], 3348 entry.data.i32[i+2], threshold->format}; 3349 outputStreams.push_back(s); 3350 } 3351 } 3352 } 3353 3354 } 3355 3356 return Status::OK; 3357} 3358 3359// Check if constrained mode is supported by using the static 3360// camera characteristics. 3361Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) { 3362 Status ret = Status::METHOD_NOT_SUPPORTED; 3363 if (nullptr == staticMeta) { 3364 return Status::ILLEGAL_ARGUMENT; 3365 } 3366 3367 camera_metadata_ro_entry entry; 3368 int rc = find_camera_metadata_ro_entry(staticMeta, 3369 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 3370 if (0 != rc) { 3371 return Status::ILLEGAL_ARGUMENT; 3372 } 3373 3374 for (size_t i = 0; i < entry.count; i++) { 3375 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO == 3376 entry.data.u8[i]) { 3377 ret = Status::OK; 3378 break; 3379 } 3380 } 3381 3382 return ret; 3383} 3384 3385// Pick the largest supported HFR mode from the static camera 3386// characteristics. 3387Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta, 3388 AvailableStream &hfrStream) { 3389 if (nullptr == staticMeta) { 3390 return Status::ILLEGAL_ARGUMENT; 3391 } 3392 3393 camera_metadata_ro_entry entry; 3394 int rc = find_camera_metadata_ro_entry(staticMeta, 3395 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry); 3396 if (0 != rc) { 3397 return Status::METHOD_NOT_SUPPORTED; 3398 } else if (0 != (entry.count % 5)) { 3399 return Status::ILLEGAL_ARGUMENT; 3400 } 3401 3402 hfrStream = {0, 0, 3403 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3404 for (size_t i = 0; i < entry.count; i+=5) { 3405 int32_t w = entry.data.i32[i]; 3406 int32_t h = entry.data.i32[i+1]; 3407 if ((hfrStream.width * hfrStream.height) < (w *h)) { 3408 hfrStream.width = w; 3409 hfrStream.height = h; 3410 } 3411 } 3412 3413 return Status::OK; 3414} 3415 3416// Check whether ZSL is available using the static camera 3417// characteristics. 3418Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) { 3419 Status ret = Status::METHOD_NOT_SUPPORTED; 3420 if (nullptr == staticMeta) { 3421 return Status::ILLEGAL_ARGUMENT; 3422 } 3423 3424 camera_metadata_ro_entry entry; 3425 int rc = find_camera_metadata_ro_entry(staticMeta, 3426 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 3427 if (0 != rc) { 3428 return Status::ILLEGAL_ARGUMENT; 3429 } 3430 3431 for (size_t i = 0; i < entry.count; i++) { 3432 if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING == 3433 entry.data.u8[i]) || 3434 (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING == 3435 entry.data.u8[i]) ){ 3436 ret = Status::OK; 3437 break; 3438 } 3439 } 3440 3441 return ret; 3442} 3443 3444// Retrieve the reprocess input-output format map from the static 3445// camera characteristics. 3446Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta, 3447 std::vector<AvailableZSLInputOutput> &inputOutputMap) { 3448 if (nullptr == staticMeta) { 3449 return Status::ILLEGAL_ARGUMENT; 3450 } 3451 3452 camera_metadata_ro_entry entry; 3453 int rc = find_camera_metadata_ro_entry(staticMeta, 3454 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry); 3455 if ((0 != rc) || (0 >= entry.count)) { 3456 return Status::ILLEGAL_ARGUMENT; 3457 } 3458 3459 const int32_t* contents = &entry.data.i32[0]; 3460 for (size_t i = 0; i < entry.count; ) { 3461 int32_t inputFormat = contents[i++]; 3462 int32_t length = contents[i++]; 3463 for (int32_t j = 0; j < length; j++) { 3464 int32_t outputFormat = contents[i+j]; 3465 AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat}; 3466 inputOutputMap.push_back(zslEntry); 3467 } 3468 i += length; 3469 } 3470 3471 return Status::OK; 3472} 3473 3474// Search for the largest stream size for a given format. 3475Status CameraHidlTest::findLargestSize( 3476 const std::vector<AvailableStream> &streamSizes, int32_t format, 3477 AvailableStream &result) { 3478 result = {0, 0, 0}; 3479 for (auto &iter : streamSizes) { 3480 if (format == iter.format) { 3481 if ((result.width * result.height) < (iter.width * iter.height)) { 3482 result = iter; 3483 } 3484 } 3485 } 3486 3487 return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT; 3488} 3489 3490// Check whether the camera device supports specific focus mode. 3491Status CameraHidlTest::isAutoFocusModeAvailable( 3492 ::android::CameraParameters &cameraParams, 3493 const char *mode) { 3494 ::android::String8 focusModes(cameraParams.get( 3495 CameraParameters::KEY_SUPPORTED_FOCUS_MODES)); 3496 if (focusModes.contains(mode)) { 3497 return Status::OK; 3498 } 3499 3500 return Status::METHOD_NOT_SUPPORTED; 3501} 3502 3503// Open a device session and configure a preview stream. 3504void CameraHidlTest::configurePreviewStream(const std::string &name, 3505 sp<ICameraProvider> provider, 3506 const AvailableStream *previewThreshold, 3507 sp<ICameraDeviceSession> *session /*out*/, 3508 Stream *previewStream /*out*/, 3509 HalStreamConfiguration *halStreamConfig /*out*/, 3510 bool *supportsPartialResults /*out*/, 3511 uint32_t *partialResultCount /*out*/) { 3512 ASSERT_NE(nullptr, session); 3513 ASSERT_NE(nullptr, previewStream); 3514 ASSERT_NE(nullptr, halStreamConfig); 3515 ASSERT_NE(nullptr, supportsPartialResults); 3516 ASSERT_NE(nullptr, partialResultCount); 3517 3518 std::vector<AvailableStream> outputPreviewStreams; 3519 ::android::sp<ICameraDevice> device3_2; 3520 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 3521 Return<void> ret; 3522 ret = provider->getCameraDeviceInterface_V3_x( 3523 name, 3524 [&](auto status, const auto& device) { 3525 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 3526 (int)status); 3527 ASSERT_EQ(Status::OK, status); 3528 ASSERT_NE(device, nullptr); 3529 device3_2 = device; 3530 }); 3531 ASSERT_TRUE(ret.isOk()); 3532 3533 sp<DeviceCb> cb = new DeviceCb(this); 3534 ret = device3_2->open( 3535 cb, 3536 [&](auto status, const auto& newSession) { 3537 ALOGI("device::open returns status:%d", (int)status); 3538 ASSERT_EQ(Status::OK, status); 3539 ASSERT_NE(newSession, nullptr); 3540 *session = newSession; 3541 }); 3542 ASSERT_TRUE(ret.isOk()); 3543 3544 camera_metadata_t *staticMeta; 3545 ret = device3_2->getCameraCharacteristics([&] (Status s, 3546 CameraMetadata metadata) { 3547 ASSERT_EQ(Status::OK, s); 3548 staticMeta = clone_camera_metadata( 3549 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 3550 ASSERT_NE(nullptr, staticMeta); 3551 }); 3552 ASSERT_TRUE(ret.isOk()); 3553 3554 camera_metadata_ro_entry entry; 3555 auto status = find_camera_metadata_ro_entry(staticMeta, 3556 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); 3557 if ((0 == status) && (entry.count > 0)) { 3558 *partialResultCount = entry.data.i32[0]; 3559 *supportsPartialResults = (*partialResultCount > 1); 3560 } 3561 3562 outputPreviewStreams.clear(); 3563 auto rc = getAvailableOutputStreams(staticMeta, 3564 outputPreviewStreams, previewThreshold); 3565 free_camera_metadata(staticMeta); 3566 ASSERT_EQ(Status::OK, rc); 3567 ASSERT_FALSE(outputPreviewStreams.empty()); 3568 3569 *previewStream = {0, StreamType::OUTPUT, 3570 static_cast<uint32_t> (outputPreviewStreams[0].width), 3571 static_cast<uint32_t> (outputPreviewStreams[0].height), 3572 static_cast<PixelFormat> (outputPreviewStreams[0].format), 3573 0, 0, StreamRotation::ROTATION_0}; 3574 ::android::hardware::hidl_vec<Stream> streams = {*previewStream}; 3575 StreamConfiguration config = {streams, 3576 StreamConfigurationMode::NORMAL_MODE}; 3577 ret = (*session)->configureStreams(config, [&] (Status s, 3578 HalStreamConfiguration halConfig) { 3579 ASSERT_EQ(Status::OK, s); 3580 ASSERT_EQ(1u, halConfig.streams.size()); 3581 *halStreamConfig = halConfig; 3582 }); 3583 ASSERT_TRUE(ret.isOk()); 3584} 3585 3586// Open a device session with empty callbacks and return static metadata. 3587void CameraHidlTest::openEmptyDeviceSession(const std::string &name, 3588 sp<ICameraProvider> provider, 3589 sp<ICameraDeviceSession> *session /*out*/, 3590 camera_metadata_t **staticMeta /*out*/) { 3591 ASSERT_NE(nullptr, session); 3592 ASSERT_NE(nullptr, staticMeta); 3593 3594 ::android::sp<ICameraDevice> device3_2; 3595 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 3596 Return<void> ret; 3597 ret = provider->getCameraDeviceInterface_V3_x( 3598 name, 3599 [&](auto status, const auto& device) { 3600 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 3601 (int)status); 3602 ASSERT_EQ(Status::OK, status); 3603 ASSERT_NE(device, nullptr); 3604 device3_2 = device; 3605 }); 3606 ASSERT_TRUE(ret.isOk()); 3607 3608 sp<EmptyDeviceCb> cb = new EmptyDeviceCb(); 3609 ret = device3_2->open(cb, [&](auto status, const auto& newSession) { 3610 ALOGI("device::open returns status:%d", (int)status); 3611 ASSERT_EQ(Status::OK, status); 3612 ASSERT_NE(newSession, nullptr); 3613 *session = newSession; 3614 }); 3615 ASSERT_TRUE(ret.isOk()); 3616 3617 ret = device3_2->getCameraCharacteristics([&] (Status s, 3618 CameraMetadata metadata) { 3619 ASSERT_EQ(Status::OK, s); 3620 *staticMeta = clone_camera_metadata( 3621 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 3622 ASSERT_NE(nullptr, *staticMeta); 3623 }); 3624 ASSERT_TRUE(ret.isOk()); 3625} 3626 3627// Open a particular camera device. 3628void CameraHidlTest::openCameraDevice(const std::string &name, 3629 sp<ICameraProvider> provider, 3630 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) { 3631 ASSERT_TRUE(nullptr != device1); 3632 3633 Return<void> ret; 3634 ret = provider->getCameraDeviceInterface_V1_x( 3635 name, 3636 [&](auto status, const auto& device) { 3637 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 3638 (int)status); 3639 ASSERT_EQ(Status::OK, status); 3640 ASSERT_NE(device, nullptr); 3641 *device1 = device; 3642 }); 3643 ASSERT_TRUE(ret.isOk()); 3644 3645 sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this); 3646 Return<Status> returnStatus = (*device1)->open(deviceCb); 3647 ASSERT_TRUE(returnStatus.isOk()); 3648 ASSERT_EQ(Status::OK, returnStatus); 3649} 3650 3651// Initialize and configure a preview window. 3652void CameraHidlTest::setupPreviewWindow( 3653 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 3654 sp<BufferItemConsumer> *bufferItemConsumer /*out*/, 3655 sp<BufferItemHander> *bufferHandler /*out*/) { 3656 ASSERT_NE(nullptr, device.get()); 3657 ASSERT_NE(nullptr, bufferItemConsumer); 3658 ASSERT_NE(nullptr, bufferHandler); 3659 3660 sp<IGraphicBufferProducer> producer; 3661 sp<IGraphicBufferConsumer> consumer; 3662 BufferQueue::createBufferQueue(&producer, &consumer); 3663 *bufferItemConsumer = new BufferItemConsumer(consumer, 3664 GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags 3665 ASSERT_NE(nullptr, (*bufferItemConsumer).get()); 3666 *bufferHandler = new BufferItemHander(*bufferItemConsumer); 3667 ASSERT_NE(nullptr, (*bufferHandler).get()); 3668 (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler); 3669 sp<Surface> surface = new Surface(producer); 3670 sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface); 3671 3672 auto rc = device->setPreviewWindow(previewCb); 3673 ASSERT_TRUE(rc.isOk()); 3674 ASSERT_EQ(Status::OK, rc); 3675} 3676 3677// Stop camera preview and close camera. 3678void CameraHidlTest::stopPreviewAndClose( 3679 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3680 Return<void> ret = device->stopPreview(); 3681 ASSERT_TRUE(ret.isOk()); 3682 3683 ret = device->close(); 3684 ASSERT_TRUE(ret.isOk()); 3685} 3686 3687// Enable a specific camera message type. 3688void CameraHidlTest::enableMsgType(unsigned int msgType, 3689 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3690 Return<void> ret = device->enableMsgType(msgType); 3691 ASSERT_TRUE(ret.isOk()); 3692 3693 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType); 3694 ASSERT_TRUE(returnBoolStatus.isOk()); 3695 ASSERT_TRUE(returnBoolStatus); 3696} 3697 3698// Disable a specific camera message type. 3699void CameraHidlTest::disableMsgType(unsigned int msgType, 3700 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3701 Return<void> ret = device->disableMsgType(msgType); 3702 ASSERT_TRUE(ret.isOk()); 3703 3704 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType); 3705 ASSERT_TRUE(returnBoolStatus.isOk()); 3706 ASSERT_FALSE(returnBoolStatus); 3707} 3708 3709// Wait until a specific frame notification arrives. 3710void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame, 3711 std::unique_lock<std::mutex> &l) { 3712 while (msgFrame != mDataMessageTypeReceived) { 3713 auto timeout = std::chrono::system_clock::now() + 3714 std::chrono::seconds(kStreamBufferTimeoutSec); 3715 ASSERT_NE(std::cv_status::timeout, 3716 mResultCondition.wait_until(l, timeout)); 3717 } 3718} 3719 3720// Start preview on a particular camera device 3721void CameraHidlTest::startPreview( 3722 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3723 Return<Status> returnStatus = device->startPreview(); 3724 ASSERT_TRUE(returnStatus.isOk()); 3725 ASSERT_EQ(Status::OK, returnStatus); 3726} 3727 3728// Retrieve camera parameters. 3729void CameraHidlTest::getParameters( 3730 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 3731 CameraParameters *cameraParams /*out*/) { 3732 ASSERT_NE(nullptr, cameraParams); 3733 3734 Return<void> ret; 3735 ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) { 3736 ASSERT_FALSE(params.empty()); 3737 ::android::String8 paramString(params.c_str()); 3738 (*cameraParams).unflatten(paramString); 3739 }); 3740 ASSERT_TRUE(ret.isOk()); 3741} 3742 3743// Set camera parameters. 3744void CameraHidlTest::setParameters( 3745 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 3746 const CameraParameters &cameraParams) { 3747 Return<Status> returnStatus = device->setParameters( 3748 cameraParams.flatten().string()); 3749 ASSERT_TRUE(returnStatus.isOk()); 3750 ASSERT_EQ(Status::OK, returnStatus); 3751} 3752 3753int main(int argc, char **argv) { 3754 ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance()); 3755 ::testing::InitGoogleTest(&argc, argv); 3756 int status = RUN_ALL_TESTS(); 3757 ALOGI("Test result = %d", status); 3758 return status; 3759} 3760